• WebCamp_インタビュー
    時間や場所にとらわれず自由に働くために必要なスキルとは?【WebCamp卒業生インタビュー】
    2018.01.26
  • WebCamp_インタビュー
    【WebCamp受講生インタビュー】起業準備中にCEOが気がついたプログラミングスキルの重要性とは?
    2017.12.25
  • WebCampPro_インタビュー
    未経験から上京し、エンジニアとしてチームラボグループに転職!【WebCampPro卒業生インタビュー】
    2018.03.10
  • WebCamp_インタビュー
    【卒業生インタビュー】台湾で月間100万UUの訪日旅行メディアを手掛けるCEOが、プログラミングを学んで得たものとは?
    2018.01.15
  • WebCamp_インタビュー
    “未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー
    2017.10.04
  • WebCamp_インタビュー
    【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!
    2018.01.15
  • WebCamp_インタビュー
    「1カ月頑張ればこの先が見えてくる」地元メディアを立ち上げたママさん
    2017.07.20
  • WebCampPro_インタビュー
    未経験31歳からエンジニア転職を実現【実際に聞いてみた】
    2017.04.01
  • WebCampPro_インタビュー
    未経験でも寿司職人からWebデザイナーになった!ホスピタリティでスクールを支える宮脇トレーナー
    2017.05.26
  • WebCamp_インタビュー
    「自信の持てるスキルを得たい!」内定辞退した女子大生がプログラミングを学習したワケ。
    2018.04.28
  • WebCampPro_インタビュー
    自分で稼ぐ力をつけるため、新卒5年目の営業マンがエンジニアに転職!【WebCampPro転職者インタビュー】
    2018.02.02

◆当サイトで人気のプログラミング教室のおすすめランキングはこちら!
プログラミングは独学では非効率で、時間を無駄にするリスクがあります。効率的なカリキュラムで学べるスクールを受講しましょう。

Web Camp【マンツーマンサポート】1ヶ月短期集中でプログラミングを学ぶスクール
1ヶ月通い放題・メンター常駐の教室環境でWebサービス等作りたい方
TechAcademyオンラインで開講しているプログラミングスクール
オンラインでどこでも学べる!/教室に行くのが忙しい人でも安心!
Tech Camp教養としてのITスキルを学べるスクール
Webデザイン/AI(人工知能)/IOS/Androidアプリ制作/VRを学びたい方!
WebCampPro転職保証付き!エンジニアとして転職したい人におすすめ!
未経験からプロのエンジニアを3ヶ月で目指すプログラミングスクールです。
11月生募集中!当社人気の転職保証コース
プログラミング学習から転職成功まで導く、当社人気のWebCamp Proコース。
10月生は満員となっております。11月生募集に向け、お早めの申込みをオススメします。
プログラミング未経験でもエンジニア転職を絶対成功させたい
スキルを身に着けて人生を自ら切り開きたい
上記にあてはまる方は、ぜひご検討ください!

はじめに

Rubyのmapメソッドは、配列やハッシュの要素ごとに処理を行った結果を、配列として返してくれるメソッドです。

そのため、データ分析をする前に、桁や文字種を合わせるなど、データ整理を行うのに使えます。

また、すでにeachやforなどの繰り返しで行っている処理を、よりシンプルに記載して、可読性を上げることができる可能性もあります。

他にも、大規模なデータを一気に処理する場合など、mapメソッドは思った以上に応用範囲が広いメソッドなのです。

そんなmapメソッドについて、詳しく解説していきましょう。

Rubyのmapとは

RubyのmapメソッドはEnumerableモジュールに定義されているメソッドですので、ArrayクラスやHashクラス、Rangeクラスなどのインスタンスで利用できるメソッドです。(その他、EnumerableモジュールをMix-inしているクラスすべてのインスタンスで利用できます)

※Arrayクラスは、配列を実現しているクラスです。詳しくは、【Ruby入門説明書】arrayについて解説を参照ください
※Hashクラスは、ハッシュを実現しているクラスです。詳しくは、【Ruby入門説明書】ハッシュについて解説を参照してください
※Rangeクラスは、(1..10)のような範囲オブジェクトのひな形です。【Ruby入門説明書】繰り返し、forについて解説で紹介しています
※モジュールやMix-inについては、【Ruby入門説明書】リファレンス、moduleについて解説を参照してください

mapの構文

mapメソッドの構文は、以下のようになっています。

オブジェクト.map do |ブロック引数|
  処理
end

ブロック引数には、オブジェクトの要素が順番に格納されて、処理が行われます。(処理にブロック引数を使わなくても問題ありません)

戻り値は、要素ごとの処理結果を集めた配列です。

なお、戻り値は必ず配列で返されます。ハッシュオブジェクトから使用した場合でも、結果は配列になりますので、注意が必要です。

動かしてみよう

では、実際にmapメソッドを動かしてみましょう。

map00-1.rb

datas = [5, 8, 1, 4, 9, 3, 6, 2, 7]

# すべてを偶数にする(奇数は2倍)
evens = datas.map do |num|
  if num.even?
    # 偶数の場合はそのまま
    num
  else
    # 奇数なので2倍する
    num *= 2
  end
end

p(datas)
p(evens)

(結果)

[5, 8, 1, 4, 9, 3, 6, 2, 7]
[10, 8, 2, 4, 18, 6, 6, 2, 14]

結果の1行めは元のdatas配列で、2行めがmapメソッドからの戻り値evensです。

この結果を比較すると、datasの要素が偶数ならそのまま、奇数なら2倍したものがevensに格納されています。つまり、要素ごとに、処理部に記載したifの分岐が行われ、その結果が要素としてevensに格納されているということです。

mapの処理

mapのブロックに記載する処理が、オブジェクトの要素数と同じ回数行われ、その結果が配列として返されます。

そのため、配列の各要素に対して、一定の処理を行う場合に利用するのが効果的です。

上で紹介しているmap00-1.rbのように、配列の中の条件を満たす要素だけに処理を施して、その他はそのままにするのも悪くありません。もちろん、条件によって、違った処理をするのも吉です。

具体的な利用シーンを、いくつか紹介しましょう。

未経験から上京し、エンジニアとしてチームラボグループに転職!【WebCampPro卒業生インタビュー】
2018-03-10 14:42
今回の記事では、たまたま見たテレビ番組がきっかけでエンジニアに興味を持ち、WebCampProを受講して見事転職を決めた中村さんにインタビューしました。 <プロフィール> 中村 駿...

入力形式の整形

inputs = ["2018/08/11","2018-7-3","2011年3月23日","2003-12-24","2016/9/8","2000年4月9日"]

dates = inputs.map do |date|
  ymd = date.split(/[\/|\-|年|月|日]/)
  date = "%#04d/%#02d/%#02d" % [ymd[0].to_i, ymd[1].to_i, ymd[2].to_i]
end

p(inputs)
p(dates)

"/"や"-"、年月日などで区切られた日付を、"/"区切りの日付(YYYY/MM/DD)に整形しています。

なお、splitメソッドについては、指定の区切り文字で文字列を分割するメソッドで、ここでは正規表現で区切り文字を複数指定しています。(詳しくは、【Ruby入門説明書】リファレンス、splitについて解説を参照ください)

また、その後の「"%#04d/%#02d/%#02d"」については、「4桁の数字/2桁の数字/2桁の数字」という書式指定の手法です。

こうすることで、データの形式が揃いますので、この後の処理で余計な分岐処理を作る必要がなくなります。

配列の合成

names = ["Ryosuke","Yuri","Kei","Hikaru","Daiki"]
points = [80,90,50,20,70]

i = 0
records = names.map do |name|
  rec = []
  rec << name
  rec << points[i]
  i += 1
  rec
end

p(records)

名前の配列と点数の配列から、名前と点数をペアにした配列の配列を生成しています。

mapメソッドの処理の中で、新しい配列の要素となるrec配列を宣言し、そこに名前と点数を追加、要素が2つの配列にして、それを返すことで、records配列に要素として取り込まれるわけです。

このように、ある配列から関連する別の配列を生成することができるのは、mapメソッドの大きな強みです。

簡略記法map(&:メソッド名)

mapメソッドだけではありませんが、配列の要素を1つずつ取り出して処理を繰り返すメソッドには、Rubyらしい簡略記法があります。

以下のようなものです。

オブジェクト.map(&:メソッド名)

このような記載をすることで、すべての要素がメソッド名のメソッドを利用した戻り値の配列が返ってきます。

言葉で説明するとややこしそうに感じますので、実際のプログラムを見てみましょう。

与えられた文字列データの文字数の配列を返すプログラムです。

まずは、通常の記法では、以下のようになります。

map01-1.rb

fruits = ["Orange","Apple","Strawberry","Kiwi","Melon","Peach"]
len = fruits.map do |fr|
  fr.length
end
p(len)

簡略記法を使うと、以下のようになります。

map01-2.rb

fruits = ["Orange","Apple","Strawberry","Kiwi","Melon","Peach"]
len = fruits.map(&:length)
p(len)

map01-1.rbに比べて、map01-2.rbは非常にシンプルに記載できています。

基本的には、既存のメソッドを利用した処理を行いたいときに利用することになるため、応用範囲は限られますが、いかにもRubyらしい記法と言えるでしょう。(特に、Ruby on Railsでは、この簡略記法が好まれています)

“未経験”でもたった1ヶ月で営業からエンジニアとして転職!『WebCamp』受講者インタビュー
2017-10-04 10:26
今回の記事では、未経験からWebCampを1ヶ月受講し、その後エンジニアとして転職をした喜田さんにお話を伺いました。 <プロフィール> 喜田 大介 さん (28歳) 大学時代はプ...

Hashのmap

冒頭で説明したとおり、mapメソッドはHashオブジェクトからも利用することができます。

配列からの利用に比べると、ハッシュからの利用は少し混乱することもありますので、改めて使い方を説明します。

ハッシュの要素は、「キー」と「値」の2つのデータのペアでできています。そのため、mapメソッドを使った場合も、ブロック引数に渡されるのはその2つの値だという点がポイントです。

つまり、Hashオブジェクトからmapメソッドを利用する場合は、ブロック引数が2つになるわけです。

Hashオブジェクト.map do |ブロック引数k, ブロック引数v|
  条件
end

※ブロック引数kにはキー、ブロック引数vには値、が入ります。

なお、ブロック引数を1つしか設定しなかった場合は、そこには[キー,値]という配列が格納されます。

実際にプログラムを作って動きを確認してみましょう

map02-1.rb

pv = {"Apple juice"=>300, "Lemon juice"=>200, "Strawberry juice"=>400, "Orange juice"=>500, "Lemon cookie"=>150, "Peach juice"=>400}

pv.map do |k, v|
  print("k, v = #{k}, #{v}\n")        # kとvに渡されているものを表示する
end

puts("-----------")
pv.map do |k|
  print("k = #{k}\n")                 # kに渡されているものを表示する
end

(結果)

k, v = Apple juice, 300
k, v = Lemon juice, 200
k, v = Strawberry juice, 400
k, v = Orange juice, 500
k, v = Lemon cookie, 150
k, v = Peach juice, 400
-----------
k = ["Apple juice", 300]
k = ["Lemon juice", 200]
k = ["Strawberry juice", 400]
k = ["Orange juice", 500]
k = ["Lemon cookie", 150]
k = ["Peach juice", 400]

このように、ブロック引数が1つでも2つでも、要素のデータを受け取ることはできます。しかし、もちろん、ブロックの処理内での扱いが違っていますので、最適な方法を採りましょう。
※迷った場合は、「どちらの方がプログラムを読みやすいか」という観点で選んでください

では、map02-1.rbですべての金額を10%引きにしてみましょう。

map02-2.rb

pv = {"Apple juice"=>300, "Lemon juice"=>200, "Strawberry juice"=>400, "Orange cookie"=>500, "Lemon cookie"=>150, "Peach juice"=>400}

# 10%割引する
discounted = pv.map do |price|
  price[1] *= 0.9
  price
end

discounted = discounted.to_h # ......(1)

p(discounted)

(結果)

{"Apple juice"=>270.0, "Lemon juice"=>180.0, "Strawberry juice"=>360.0, "Orange cookie"=>450.0, "Lemon cookie"=>135.0, "Peach juice"=>360.0}

なお、(1)の行は、戻り値をハッシュに変換している処理です。

前述していますが、mapメソッドの戻り値は配列になっています。そのため、ハッシュとして取得するためには、変換してやる必要があるのです。

コツコツ独学×スクールで実践。未経験からエンジニアに転職!【WebCamp卒業生インタビュー】
2018-03-22 23:28
今回の記事では、独学でPHPを1年半学習し、その後WebCampを受講して未経験からエンジニアへと転職された佐々木さんにお話を伺いました。 <プロフィール> 佐々木 祐樹 さん(2...

破壊的メソッドmap!

他のいくつかのメソッドと同様に、mapメソッドにも自分自身を書き換えてしまう破壊的メソッドmap!が存在しています。

破壊的メソッドをうまく使えば、余計な変数を減らして、プログラムをシンプルに記載することができますので、使い方を練習しておきましょう。

なお、破壊的メソッドを使うときのポイントは、「元のデータを後でもう一度使うかどうか」です。使う必要がない(処理上、改めて取得するなど)場合は、躊躇せず破壊的メソッドを利用することをおすすめします。

ただし、Hashオブジェクトからはmap!メソッドは利用できませんので、注意が必要です。

例えば、最初に紹介した与えられた配列の値を偶数にする処理(map00-1.rb)の場合、おそらくこの後の処理のための前準備ですので、変更前の処理は不要でしょう。むしろ、余計な変数が多くなると混乱の元になりますので、破壊的メソッドを使うべきなのです。

map00-2.rb

datas = [5, 8, 1, 4, 9, 3, 6, 2, 7]
datas.map! do |num|
  if num.even?
    num
  else
    num *= 2
  end
end

p(datas)

(結果)

[10, 8, 2, 4, 18, 6, 6, 2, 14]

データを受け取る変数が不要となりましたので、よりシンプルになっています。

問題「値段改定」

次のような金額リストがあります。300円以上は5%値下げ、300円未満は5%値上げしたリストを作ってください。

pv = {"Apple juice"=>300, "Lemon juice"=>200, "Strawberry juice"=>400, "Orange cookie"=>500, "Lemon cookie"=>150, "Peach juice"=>400}

まとめ

mapメソッドの基本的な構文と使い方を説明しました。

mapメソッドは、何らかのデータ処理をする前のデータ整形や桁合わせなど、「すべてのデータに対して同じ処理を行う」ときに、とてもシンプルな記載ができます。

プログラムというのは、データを扱うこととほぼ同義ですので、mapメソッドを使う機会は、少なくありません。

また、mapメソッドを使うことで、eachなどの繰り返し処理をシンプルに書き換えることができる場合もあります。

特に、プログラムの規模が大きくなれば、ますますこれらの傾向は強くなりますので、今のうちに基本をしっかりと押さえておきましょう。

・mapメソッドは、Enumerableモジュールに定義されており、ArrayクラスやHashクラスにMix-inされている
・mapメソッドは、各要素に同じ処理を施した結果の配列を返す
・既存のメソッドを使うのであれば、簡略記法を使う方がシンプルになる
・Hashからmapメソッドを使うときには、処理内容に合わせてブロック引数の数を変えた方が処理がシンプルになる
・mapメソッドは、処理結果の配列を返す。map!は自分自身を処理結果で上書きして返す
・Hashのmapメソッドには、破壊的メソッドmap!がない

問題の答え

pv = {"Apple juice"=>300, "Lemon juice"=>200, "Strawberry juice"=>400, "Orange cookie"=>500, "Lemon cookie"=>150, "Peach juice"=>400}

discounted = pv.map do |price|
  if price[1] < 300
    # 5%値上げする
    price[1] *= 1.05
  else
    # 5%値引きする
    price[1] *= 0.95
  end
  price
end

discounted = discounted.to_h # ......(1)

p(discounted)

WebCampOnline プログラミングコースについて

WebCampでは、「どこでも学べる」オンラインコースを開講しています。

初心者・未経験の方でもわずか1ヶ月でプログラミングの基礎を学び、アプリケーション開発をすることができます。

WebCampOnlineが選ばれる3つの理由

1.学習の仕方がわからなくても安心!初心者に寄り添った学習カリキュラム

これから学習を始める初心者の方や、独学で挫折してしまった方に向けて、アプリケーション作成をゴールとする一気通貫したカリキュラムを提供しています。2500名を輩出しているWebCampだからこその教室でのリアルな受講生の声を反映し、オンラインコースでも初心者に寄り添った学習体験をご提供いたします。

2.つまずいたらすぐ解決!プロのエンジニアに質問し放題

プログラミング学習で挫折する理由の多くは「つまずいた時に聞ける人がいない」ことです。オンラインコースでは、現役エンジニアやプロ講師に、すぐにチャットでの質問が可能です。つまずきをすぐに解消できるので、挫折せずに学習を継続することができます

3.1ヶ月間で終わらなくても大丈夫!カリキュラムは"卒業後"も"無料"で利用可能

受講したいけど、仕事が急に忙しくなるかもしれないから受講するか迷っている・・・そんな方も多いのではないでしょうか?ご安心ください。カリキュラムは期間終了後も「無料」で使うことができます。また、しっかり学習時間を確保した方も、振り返って学習することでプログラミングスキルがご自身に馴染んできます。

▼まずは無料でWebデザインのカリキュラムを体験しよう!

【インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!

ブラジルから帰国し技術をつけようとRubyエンジニアを目指してWebCampでRubyを学び、見事Webエンジニアとして転職を果たした田中さんにお話を伺いました。

Rubyの学習がしたい。基礎をしっかりと理解したい

転職のサポートがほしい

と考えている方はぜひお読み下さい。

【WebCamp卒業生インタビュー】1ヶ月でRubyをゼロから学び、Webエンジニアとして転職!
2018-01-15 13:23
今回の記事では、WebCampで1ヶ月間Rubyを学習し、Webエンジニアとして転職した卒業生の田中さんにお話を伺いました。 <プロフィール> 田中 デニス 昭彦さん(...
関連キーワード
Rubyの関連記事
  • 【Ruby入門説明書】rescueについて解説
  • 【Ruby入門説明書】jsonについて解説
  • 【Ruby入門説明書】csvについて解説
  • 【Ruby入門説明書】mapについて解説
  • 【Ruby入門説明書】gemsについて解説
  • 【Ruby入門説明書】ruby sliceについて解説
おすすめの記事
Infratop
こんにちは、インフラトップでCTOをしている田中です。 今回はクリエイティブチームの文化や制度を紹介します。 フォワード まず文化として、プ...
Ruby
プログラムでデータを扱うとき、不正なデータや誤差の大きいデータなど、無意味なデータが含まれていることは少なくありません。そのため、与えられた...