2011-03-10 99 views
72
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陣列#每個與陣列#地圖

這裏發生了什麼事?

回答

137

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

完美的答案理解。只是.. 免責聲明:如果您過度使用map函數的返回值,您可能會浪費大量內存。 – Imran 2017-02-26 08:02:41

0

當您使用映射到一個哈希值,它隱含鑄散列到一個數組,所以你必須

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

vs.each {...}只給你回過去的評價,這是[對於[「d」,[11,22]]和[33,44,55]中的[「f」,[33,44,55]]。所以前的最後加入,你有

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

side effects是其加入一些混亂到相同的逆向工程。

是的,無論是迭代這個數組(實際上,在任何在Enumerable混合),但map將返回塊結果所組成的陣列,而each將只返回原始數組。

返回值each只是原始數組,很少用於Ruby代碼,但mapmost important functional tools之一。

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, ...] 

順便說一句,你可能有很難找到文檔,因爲地圖中的方法枚舉各自要求的一種方法可枚舉模塊)是陣列中的一種方法。

作爲一個瑣事注意:地圖實施是基於每個

2

.each返回您最初提供的相同的陣列:

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

.map返回一個新數組出每塊調用的結果:

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

這裏的地圖,從如何不同的快速演示每個

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

因此,每個用於處理數組和地圖用於處理數組。

0

陣列#每個方法返回同一陣列

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 

陣列#地圖方法返回一個新的數組

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