Array#eachとArray#map


92
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です。

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

回答:


174

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"]

理解するのに最適な答え。ただa ..免責事項:map関数の戻り値を使いすぎると、大量のメモリを浪費する可能性があります。
Imran Ahmad

33

副作用は、あなたのリバースエンジニアリングに混乱を追加していると同じです。

はい、どちらも配列に対して(実際には、Enumerableに混在するすべてに対して)反復処理を行いますが、mapはブロックの結果から構成される配列を返しますが、それぞれは元の配列を返すだけです。

それぞれの戻り値は元の配列にすぎず、Rubyコードではほとんど使用されませんが、map最も重要な機能ツールの 1つです。

どのようなmap行いは、ブロックまたは渡された名前のメソッドの結果を含む配列を返すことです。例えば:

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

この場合、私はブロックを渡さずにを渡しましたがSymbolclass Symbolオブジェクトには次のto_procような結果になるメソッドがあります:

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

ところで、あなたがので、ドキュメントを見つけるのに苦労してもよい地図は方法である列挙しながら、(によって必要とされる一の方法列挙モジュールが)方法である配列が

雑学として:マップの実装はそれぞれに基づいています


13

これは、マップがそれぞれとどのように異なるかを示す簡単なデモです

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_a", "map_b", "map_c"]それぞれが反復するだけで元の配列を返すのに対して、マップが戻ることがわかります["a", "b", "c"]

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


4

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

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

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

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

1

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

0

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

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

vs.each {...}は、最後の評価のみを返します。["d"、[11、22]]は[11、22]、["f"、[は[33、44、55]です。 33、44、55]]。したがって、最後の参加の前に、

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

0

ソース配列を変更mapする強打map!で使用することもできます


これは質問に対する答えではありません。問題はeach、指定されたブロックを実行して元の配列を返すとの違いです。and mapは、ブロックの実行結果を値として含む配列を返します
Sampson Crowley
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.