配列やハッシュの要素に対して1つずつ処理したいことがあります。Rubyにはこのようなときに便利な map, map! というメソッドが用意されています。
map, map! メソッドとは
map は、配列の要素の数だけブロック内の処理を繰り返し、結果として作成された配列を返します。map は元の値に対して影響を与えないのに対し、 map! は元の値を書き換えます。また、Rubyには collect メソッドがありますが、これは map メソッドの別名です。
map メソッドの記述方法
map メソッドの記述方法は以下の通りです。
1 2 3 |
オブジェクト.map { |変数| # 実行したい処理 } |
配列やハッシュオブジェクトの要素がひとつずつ取り出され変数に要素が代入されていき、指定した変数名をブロック内で使用することができます。
ハッシュに対して使うときは注意
ハッシュに対してmapを使うことはできますが、その返り値はハッシュではなく配列になるので注意が必用です。また、map!メソッドはハッシュに対しては使用できません。
配列に map を適用する
以下のプログラムは配列のすべての要素を2倍する例です。
1 2 3 |
a1 = [100, 200, 300] a2 = a1.map { |x| x * 2 } p a2 # [200, 400, 600] |
まず、配列 a1 から100という要素を取り出し x に代入されます。|x| というのが1つの要素を取り出して x と名付けることを示しています。その後の x * 2 が実行され、戻り値の配列の要素に追加されます。次に200という要素に対して同様の処理が行われ、最後に300という要素に同様の処理が行われます。
上の例では、結果として得られた配列を a2 に代入しています。 a2 を出力するとすべての要素が2倍されていることが確認できます。
例では結果を別の変数に入れていますが、結果さえ得られれば元のデータは必要ない場合もあります。mapは元のデータはそのままですが map! を使えば新しく変数を用意する必要がありません。
1 2 |
a = [100, 200, 300] p a.map! { |x| x * 2 } # [200, 400, 600] |
Rubyではこのように、元のデータを書き換えてしまうメソッド名には末尾に ! が付けられています。
ハッシュに map を適用する
配列だけでなくハッシュにも map を適用することができます。
1 2 |
h = { "apple" => 100, "orange" => 200, "grape" => 300 } p h.map { |key, value| [key, value * 2] } # [["apple", 200], ["orange", 400], ["apple", 600]] |
上の例では、ハッシュのキーが「key」に代入され、値が「value」に代入されていき、ブロック内の処理が繰り返されていきます。ハッシュで map を使用する場合でも戻り値は配列であることに注意してください。
また、to_h メソッドを利用することで戻り値の配列をハッシュに変換できます。
1 2 |
h = { "apple" => 100, "orange" => 200, "grape" => 300 } p h.map { |key, value| [key, value * 2] }.to_h # {"apple"=>200, "orange"=>400, "grape"=>600} |
ただし、to_h メソッドは Ruby 2.1 以降でしか使用できないので注意してください。
map の&とメソッドを使用した省略記法
各要素にメソッドを適用するときは以下のように省略して記述することができます。
1 |
オブジェクト.map(&:メソッド名) |
省略して記述した場合は、すべての要素に対して&の後にシンボルで指定したメソッドが繰り返し実行され、結果が配列として返されます。
1 2 |
a = ["APPLE", "ORANGE", "GRAPE"] p a.map(&:downcase) # ["apple", "orange", "grape"] |
上の例では、各要素に対して downcase メソッドが実行され、結果の配列が返されます。このように省略記法を使えば、変数を使用することなく非常に簡潔に記述できます。