web-dev-qa-db-ja.com

Array#eachとArray#map

hash = { "d" => [11, 22], "f" => [33, 44, 55] }

# case 1
hash.map {|k,vs| vs.map {|v| "#{k}:#{v}"}}.join(",")
=> "d:11,d:22,f:33,f:44,f:55"

# case 2
hash.map {|k,vs| vs.each {|v| "#{k}:#{v}"}}.join(",")
=> "11,22,33,44,55"

唯一の違いは、ケース1がvs.mapを使用し、ケース2がvs.eachを使用することです。

ここで何が起こったのですか?

88
user612308

Array#eachは、配列の各要素に対して指定されたブロックを実行し、配列自体を返します。

Array#mapは、配列の各要素に対して指定されたブロックも実行しますが、その値がブロックの各反復の戻り値である新しい配列を返します。

例:このように定義された配列があると仮定します:

arr = ["tokyo", "london", "rio"]

それからeachを実行してみてください:

arr.each { |element| element.capitalize }
# => ["tokyo", "london", "rio"]

戻り値は単純に同じ配列であることに注意してください。 eachブロック内のコードは実行されますが、計算された値は返されません。また、コードには副作用がないため、この例は有用な作業を行いません。

対照的に、配列のmapメソッドを呼び出すと、要素がmapブロックを実行する各ラウンドの戻り値である新しい配列が返されます。

arr.map { |element| element.capitalize }
# => ["Tokyo", "London", "Rio"]
170
Olives

副作用 は同じであり、リバースエンジニアリングに混乱をもたらします。

はい、両方とも配列を繰り返し処理します(実際には Enumerable )が混在するものを繰り返し処理しますが、 mapeach であるブロックの結果で構成される配列は、元の配列を返すだけです。

each の戻り値は元の配列であり、Ruby code but map最も重要な機能ツール の1つです。

mapは、渡されたブロックまたは名前付きメソッドの結果を含む配列を返します。例えば:

    2.2.3 :001 > [:how, :now, :brown, :cow].map &:to_s
 => ["how", "now", "brown", "cow"]

この場合、ブロックは渡さず、Symbolだけを渡しましたが、class Symbolオブジェクトにはto_proc結果となるメソッド:

[:how.to_s, :now.to_s, ...]

ところで、mapEnumerable while eachのメソッドであるため、ドキュメントを見つけるのに苦労しているかもしれません。 Enumerable module)はArrayのメソッドです。

雑学メモ:mapの実装はeachに基づいています。

33
DigitalRoss

マップがそれぞれの違いを示す簡単なデモを次に示します

a = ["a", "b", "c"];
#Array.map
p a.map {|item| "map_" + item}
#prints ["map_a", "map_b", "map_c"]

#Array.each
p a.each {|item| "map_" + item}
#prints ["a", "b", "c"]

Mapは["map_a", "map_b", "map_c"]を返すのに対し、それぞれは単に反復するが元の配列["a", "b", "c"]を返します。

したがって、それぞれが配列の処理に使用され、マップは処理された配列で何かをするために使用されます。

13
Rima

.eachは、最初に指定したのと同じ配列を返します。

[1,2,3].each { |i| i + 1 }
#=> [1,2,3]

.mapは、各ブロック呼び出しの結果から新しい配列を返します。

[1,2,3].map { |i| i + 1 }
#=> [2,3,4]
4
pastullo

Array#eachメソッドは同じ配列を返します

a = [1,2,3,4,5]
a.object_id #70284994490700

b = a.each {|n| n + 2}
p b #[1,2,3,4,5]
b.object_id #70284994490700 <<--- it's the same as a

Array#mapメソッドは新しい配列を返します

c = [1,2,3,4,5]
c.object_id #70219117705860

d = c.map {|n| n + 2}
p d #[3,4,5,6,7]
d.object_id #70284994343620  <<---- it's different than c
1
user3007294

mapをハッシュに使用すると、暗黙的にハッシュが配列にキャストされるため、

[["d", [11, 22]], ["f", [33, 44, 55]]]

vs.each {...}は、最後の評価のみを返します。これは、["d"、[11、22]]の場合は[11、22]、["f"、[ 33、44、55]]。最後の参加前に

[[11, 22], [33, 44, 55]]
0
sawa