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

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

4

7 に答える 7

188

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"]
于 2011-03-10T00:42:39.000 に答える
35

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

はい、両方とも配列を反復処理します(実際には、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, ...]

ところで、 mapEnumerableのメソッドであり、それぞれ( Enumerableモジュールで必要な1つのメソッド)はArrayのメソッドであるため、ドキュメントを見つけるのに苦労している可能性があります。

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

于 2011-04-19T16:02:45.087 に答える
14

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

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

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

于 2014-05-19T16:41:55.247 に答える
4

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

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

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

[1,2,3].map { |i| i + 1 }
#=> [2,3,4]
于 2014-04-23T18:37:01.253 に答える
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
于 2017-11-02T18:07:21.287 に答える
0

map to hashを使用すると、暗黙的にハッシュが配列にキャストされるため、次のようになります。

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

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

[[11, 22], [33, 44, 55]]
于 2011-03-10T00:42:37.210 に答える
0

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

于 2020-03-26T16:07:15.900 に答える