rubyのeach, mapの違い
すごく初歩的ですが、新年一発目のエントリは去年の積み残しから。
each
[1] pry(main)> def each_sample [1] pry(main)* (1..10).to_a.each do |i| [1] pry(main)* piyo = i + 1 [1] pry(main)* end [1] pry(main)* end => :hoge [2] pry(main)> hoge = each_sample() => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
http://ref.xaio.jp/ruby/classes/array/each
eachメソッドは、配列の要素の数だけブロックを繰り返し実行します。繰り返しごとにブロック引数には各要素が順に入ります。戻り値はレシーバ自身です。
レシーバ自身 が返るので、いくら中で piyo
に代入したところで戻り値としては i
が返り値になる。
map
[1] pry(main)> def map_sample [1] pry(main)* (1..10).to_a.map do |i| [1] pry(main)* piyo = i + 1 [1] pry(main)* end [1] pry(main)* end => :huga [2] pry(main)> huga = map_sample() => [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
http://ref.xaio.jp/ruby/classes/array/map
mapメソッドは、要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返します。collectメソッドの別名です。
mapはeachとは違い、要素を使ってブロックを実行しブロックの戻り値を集めて返すようになっている。つまり中で定義した piyo
を 集めた配列 を作成して返すのでインクリメントされた配列が返り値になる。
どのように使い分けるか
eachはレシーバが返るだけなので、「受け取って何かをする」という処理ではなく、もともとのレシーバの中で何かを再帰的に処理したい場合に使うケースが多い。
例えば「複数のユーザーを検証し、(何らかの)ポイントを付与する」といった処理は下記のように書ける。
users.each do |user| user.add_point if user.valid? end
一方でmapはブロックの戻り値が返るので、レシーバに対して再帰的に処理したオブジェクトを配列として利用したい場合に利用するケースが多い。
例えば、「複数のユーザーに付与されたポイントを取得したい」といった処理は下記のように書ける。
# 各ユーザーのポイントを再帰的に取得する user_points = users.map do |user| user.point end # 上記の例の場合、更に簡潔に書ける user_points = users.map(&:point)
今年もよろしくお願いいたします。
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る