【Ruby】mapメソッドの使い方は?eachとの違いや発展的な使い方について現役エンジニアが解説
この記事では、
- RubyでのArray操作をもっと効率的に行いたい
- シンプルで簡潔なコードを書いてみたい
- eachメソッドとmapメソッドの違いを明確に理解したい
という悩みを抱えている向けに、
- mapメソッドの基本情報と使い方
- mapメソッドの応用的な使い方と例
- mapメソッドとeachメソッドの比較
についてRailsエンジニアである私が解説していきたいと思います。
Rubyに関して言うと、mapメソッドはほぼマストで使えた方がよいメソッドになるので、ぜひ使えるようになりましょう。特にeachで冗長に書かざるを得ない状態で、mapはかなり綺麗にかけるのでおすすめです。
著者:
IT系キャリアに関して情報発信しているDAINOTEを運営。自身も自社プロダクトであるMedia Analyticsの開発をRuby on Railsで行うWebエンジニアである。本業はWebマーケター。最近は生成AI系の開発にどハマり中。著書は独学プログラマーのためのAIアプリ開発がわかる本 。詳細は運営者情報をご覧ください。
目次 (PRも含まれます)
- 1 mapメソッド:要素に対してiterationを実行して、配列で返すメソッド
- 2 mapメソッドの基本的な使い方
- 3 mapメソッドが便利な場面:eachメソッドで配列に追加する処理を簡単に書ける
- 4 mapメソッドとcollectメソッドの関係: mapメソッドのエイリアス(同名です)
- 5 mapメソッドの省略した書き方:symbol.to_procを使った省略形
- 6 Hashでmapメソッドを使う方法
- 7 mapメソッドとmap!メソッドの違いは?
- 8 インデックス付きで操作するmap.with_indexメソッドの活用
- 9 map後にnilを取り除く: compact
- 10 map後に多次元配列を一次元配列にする: flatten
- 11 mapメソッドを使ってみよう!
- 12 map!メソッドも使ってみよう!
- 13 mapをhashで利用する方法
- 14 類似メソッドとの違いについて
- 15 他の配列操作メソッドについて
- 16 まとめ
mapメソッド:要素に対してiterationを実行して、配列で返すメソッド
Rubyでは、配列(Array)やハッシュ(Hash)の各要素に対して一定の処理を行い、その結果を新たな配列として返す方法としてmap
メソッドがよく使用されます。map
メソッドは、配列の各要素に対してブロック内の処理を適用した結果を集めて、新しい配列を作ります。このメソッドは非常に便利で、Rubyで配列やハッシュを扱う際には頻繁に用いられるメソッドの一つです。
numbers = [1, 2, 3, 4, 5]
squared_numbers = numbers.map { |number| number ** 2 }
puts squared_numbers
# 結果: [1, 4, 9, 16, 25]
map
メソッドは、コードを簡潔に書けるだけでなく、コードの意図が明確になり読みやすくなる利点があります。
mapメソッドの基本的な使い方
map
メソッドを用いる基本的な形式は、配列やハッシュに対して.map
を呼び出し、その後ろにブロック({}
)を記述します。このブロック内で、各要素に対する処理を記述します。最終的に、このブロックの処理結果を元にした新しい配列が返されます。
例えば、次のコードでは、各要素の2倍を計算して新しい配列を作る例を示しています。
numbers = [1, 2, 3, 4, 5]
doubled_numbers = numbers.map { |number| number * 2 }
puts doubled_numbers
# 結果: [2, 4, 6, 8, 10]
each do
でも同じように書くこともできますよ!numbers = [1, 2, 3, 4, 5]doubled_numbers = numbers.each do |number|
number * 2
end
puts doubled_numbers
# 結果: [2, 4, 6, 8, 10]
mapメソッドが便利な場面:eachメソッドで配列に追加する処理を簡単に書ける
mapメソッドは、繰り返し処理をした結果を配列で受け取りたい時に便利です。
each
メソッドも配列の各要素に対して処理を行いますが、each
は各要素に対する処理の結果を集めて新しい配列を返すことはありません。
代わりに、もとの配列自体を変更せずに、単に各要素に対して指定したブロックの処理を実行します。
そのため、新しい配列を作成したい場合はmap
メソッドの使用が適しています。
numbers = [1, 2, 3, 4, 5]
doubled_numbers = []
numbers.each { |number| doubled_numbers << number * 2 }
puts doubled_numbers
# 結果: [2, 4, 6, 8, 10]
上記のeach
メソッドの例でも同じ結果が得られますが、map
メソッドを使う方がよりシンプルで直接的です。
関連:【Ruby】eachメソッドの使い方の基礎から応用まで現役エンジニアが解説します
mapメソッドとcollectメソッドの関係: mapメソッドのエイリアス(同名です)
collect
メソッドは、Rubyでmap
メソッドと同じ役割を果たします。
実は、collect
とmap
は互換性があり、どちらも配列の各要素に対してブロック内の処理を適用し、その結果を新しい配列として返します。
この2つのメソッドは内部的には同じ動作をするため、使用するメソッドは好みやプロジェクト内のコーディング規約に依存します。
例えば以下のコードでは、map
メソッドとcollect
メソッドが同じ結果を返すことを示しています。
numbers = [1, 2, 3, 4, 5]
squared_numbers_map = numbers.map { |number| number ** 2 }
puts squared_numbers_map
# 結果: [1, 4, 9, 16, 25]
squared_numbers_collect = numbers.collect { |number| number ** 2 }
puts squared_numbers_collect
# 結果: [1, 4, 9, 16, 25]
mapメソッドの省略した書き方:symbol.to_procを使った省略形
Rubyでは、ブロックを使うメソッドに対して省略した記述法がよく用いられます。
特に、map
メソッドを使用する際には、この省略形が便利です。省略形を使うと、コードがさらに簡潔になり、読みやすくなります。
numbers = [1, 2, 3, 4, 5]
# ブロックを使わずに:symbol.to_procを使った省略形
squared_numbers = numbers.map(&:to_s)
puts squared_numbers
# 結果: ["1", "2", "3", "4", "5"]
上記のコードでは、to_s
メソッドが各要素に対して呼び出され、数字を文字列に変換しています。
この省略形は、メソッド呼び出しが各要素に対して単一で、引数が不要な場合に特に有効です。
Hashでmapメソッドを使う方法
map
メソッドは、配列だけでなくハッシュに対しても使用することができます。
ハッシュを使用する場合、ブロック変数はキーと値のペアとして取り扱われます。
capitals = { japan: 'Tokyo', france: 'Paris', italy: 'Rome' }
# キーを大文字に変換する
upcased_capitals = capitals.map { |country, capital| [country.to_s.upcase, capital] }.to_h
puts upcased_capitals
# 結果: {"JAPAN"=>"Tokyo", "FRANCE"=>"Paris", "ITALY"=>"Rome"}
このコードでは、ハッシュの各要素(国とその首都)に対して処理を行い、国名を大文字に変換しています。
最後にto_h
メソッドを用いて、配列の配列をハッシュに変換しています。
mapメソッドとmap!メソッドの違いは?
map
メソッドには破壊的なバリエーションであるmap!
メソッドも存在します。
map!
メソッドは、元の配列自体を変更して、新しい値で更新します。これに対し、map
メソッドは元の配列を変更せず、新しい配列を作成します。
numbers = [1, 2, 3, 4, 5]
numbers.map! { |number| number ** 2 }
puts numbers
# 結果: [1, 4, 9, 16, 25]
map!
メソッドを使用する際には、元の配列が変更されることを意識する必要があります。状況に応じて、map
メソッドとmap!
メソッドを適切に選択してください。
インデックス付きで操作するmap.with_indexメソッドの活用
map.with_index
メソッドを使用すると、ブロック内で各要素のインデックスも扱うことができます。これにより、要素自体だけでなくその位置情報を利用した処理が可能になります。
# map.with_indexメソッドの使用例:
fruits = ['apple', 'banana', 'cherry']
capitalized_fruits_with_index = fruits.map.with_index { |fruit, index| [index, fruit.capitalize] }.to_h
puts capitalized_fruits_with_index.inspect
出力結果:
{0=>"Apple", 1=>"Banana", 2=>"Cherry"}
この例では、map.with_index
を使用して各要素を大文字に変換し、そのインデックスとともに新しいハッシュを生成しています。map.with_index
を使うことで、位置情報を保持しながら配列の各要素を加工する処理を容易に実現できます。
map後にnilを取り除く: compact
配列の変換処理の結果、nil
が含まれる場合があります。そういった場合には、compact
メソッドをチェーンさせることでnil
を簡単に取り除くことができます。
numbers = [1, 2, nil, 4, 5]
non_nil_numbers = numbers.map { |n| n ? n * 2 : nil }.compact
p non_nil_numbers
実行結果:
[2, 4, 8, 10]
map後に多次元配列を一次元配列にする: flatten
map
の結果得られた配列がネストしている場合、flatten
メソッドを使って平坦化(多次元配列を一次元配列に変換)することができます。
nested_arrays = [[1, 2], [3, 4], [5, 6]]
flattened_and_doubled = nested_arrays.map { |array| array.map { |n| n * 2 }}.flatten
p flattened_and_doubled
実行結果:
[2, 4, 6, 8, 10, 12]
mapメソッドを使ってみよう!
Rubyのmap
メソッドを使用することで、配列やハッシュの各要素に対して一括で処理を実行し、その結果を新たな配列として得ることができます。この機能は、データの変換や加工を効率的に行いたい場合に非常に便利です。
例えば、次のコードでは、配列内の各数値を文字列に変換しています。
numbers = [1, 2, 3, 4, 5]
string_numbers = numbers.map { |number| number.to_s }
puts string_numbers
# 結果: ["1", "2", "3", "4", "5"]
このように、map
メソッドを使用すると、配列の各要素を効率的に操作することが可能です。複雑な処理も、ブロック内に記述することで簡単に表現できます。
実践練習:具体的に処理を見てみる
map
メソッドは、単にデータ型を変換するだけでなく、より具体的な処理を行うこともできます。たとえば、次のコードでは、配列の各要素に3を加えた新しい配列を作成しています。
numbers = [1, 2, 3, 4, 5]
added_numbers = numbers.map { |number| number + 3 }
puts added_numbers
# 結果: [4, 5, 6, 7, 8]
この例のように、map
メソッドを使えば、配列の各要素に対して一定の加算処理を行い、その結果を新しい配列として返すことができます。同様にして、他の算術演算や条件式を用いた複雑な操作も実現可能です。
実践練習:戻り値を使用する
map
メソッドの大きな特徴は、ブロックの最後に評価された式の結果が新しい配列の要素として追加されることです。この戻り値を活用することで、さまざまなデータ変換を効率的に行うことができます。
次の例では、配列の各要素が偶数であればそのまま、奇数であれば2を乗じた値を新しい配列として返しています。
numbers = [1, 2, 3, 4, 5]
processed_numbers = numbers.map do |number|
if number.even?
number
else
number * 2
end
end
puts processed_numbers
# 結果: [2, 2, 6, 4, 10]
このようにmap
メソッドを用いることで、条件分岐を含む複雑なロジックも、配列の各要素に適用し、新たな配列を得ることができます。これにより、コードの可読性と効率性を同時に向上させることが可能になります。
map!メソッドも使ってみよう!
map!
メソッドを利用することで、配列の各要素に処理を適用し、その結果で元の配列自体を更新することができます。このメソッドは、map
メソッドと似ていますが、元の配列の内容を直接変更する点が異なります。
numbers = [1, 2, 3, 4, 5]
numbers.map! { |number| number ** 2 }
puts numbers
# 結果: [1, 4, 9, 16, 25]
この例では、配列numbers
の各要素を二乗し、その結果で元の配列numbers
を更新しています。これは、データの変換結果を追加の変数や配列に保存する必要がない場合に有用です。ただし、map!
を使用する際には、元の配列が変更されることに注意しましょう。状況に応じて、元のデータを保持する必要がある場合はmap
メソッドを使用する方が適切です。
mapをhashで利用する方法
Rubyのmap
メソッドは、配列だけでなくハッシュに対しても使用することができます。ハッシュの場合、map
メソッドはキーと値のペアに対してブロック内の処理を適用し、結果を新しい配列として返します。
例えば、ハッシュの各値に特定の処理を適用したい場合、次のようにmap
メソッドを使用することができます。
capitals = { japan: 'Tokyo', france: 'Paris', italy: 'Rome' }
uppercased_capitals = capitals.map { |key, value| [key, value.upcase] }.to_h
puts uppercased_capitals
# 結果: {:japan=>"TOKYO", :france=>"PARIS", :italy=>"ROME"}
この例では、ハッシュcapitals
の各値(都市名)を大文字に変換しています。ブロック内でキーと値のペアを[key, value.upcase]
の形式で返し、最後にto_h
メソッドを使用して配列の配列をハッシュに変換しています。
ハッシュの場合、map
メソッドはキーと値のペアに対して自由に処理を加えることができるため、データ加工の幅が広がります。これにより、柔軟なデータ処理が可能になります。
関連:【Ruby】 hashの使い方完全マニュアル | 追加, 更新, 削除, 高度な利用方法について現役エンジニアが解説します
類似メソッドとの違いについて
selectとの違い
select
メソッドは、特定の条件に合致する要素のみを抽出するために使用されます。これに対してmap
メソッドは、配列やハッシュの全ての要素に対して処理を適用し、その結果からなる新しい配列を生成します。つまり、select
メソッドはフィルタリングに、map
メソッドは各要素の変換に利用されるという違いがあります。
関連:【Ruby】 selectメソッド完全マニュアル | 基礎から応用・filterとの違いについても解説
collectとの違い
前述のとおり、collect
メソッドはmap
メソッドと全く同じ機能を持ち、互換性があります。つまり、collect
とmap
の間に機能的な違いはありません。どちらを使用するかは、個人の好みやプロジェクトのコーディング規約に依存します。
eachとの違い
each
メソッドも配列やハッシュの各要素に対して処理を実行しますが、each
は処理の結果を集めて新しい配列を返すことはしません。each
は各要素に対して指定したブロックの処理を実行するだけで、元の配列やハッシュを変更することなく、戻り値として元の配列やハッシュをそのまま返します。map
メソッドと異なり、each
を使っても新しい配列や変換されたデータを得ることはできません。
関連:【Ruby】eachメソッドの使い方の基礎から応用まで現役エンジニアが解説します
他の配列操作メソッドについて
Rubyでは、map
やselect
のようなメソッド以外にも、配列を効率的に操作するための様々なメソッドが提供されています。例えば、reduce
(またはinject
)、filter
、all?
、any?
、none?
、find
など、配列やハッシュのデータを加工・調査するための多くのメソッドがあります。これらのメソッドを学ぶことで、より複雑なデータ処理や条件分岐、集計などを効率的に行うことができるようになります。
まとめ
本記事では、Rubyのmap
メソッドの使い方、応用的な使い方、類似メソッドとの違いについて解説しました。配列やハッシュの各要素に対して処理を行い、その結果を新しい配列やハッシュとして返すmap
メソッドは、Rubyプログラミングにおいて非常に便利なツールです。このメソッドを使いこなすことで、コードの記述を簡潔にし、プログラムの可読性と効率性を向上させることができます。また、select
やeach
といった他の配列操作メソッドと組み合わせることで、より柔軟なデータ処理を行うことが可能になります。ぜひこの機会に、map
メソッドを活用していろいろなコードを書いてみてください。