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

这里发生了什么?

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

副作用是一样的,这就给你的逆向工程添加了一些混乱。

是的,两者都迭代数组(实际上是在Enumerable中混合的任何东西),但是map将返回一个由块结果组成的数组,而每个数组只会返回原始数组。

每一个的返回值只是原始数组,在Ruby代码中很less使用,但是map是最重要的function工具之一 。

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

顺便说一句,你可能很难find文档,因为mapEnumerable中的一个方法,而每个Enumerable模块所需的一个方法)是Array中的一个方法。

作为一个琐事笔记: 地图实施是基于每个

下面是一个地图不同的快速演示

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

所以每个用于处理数组,地图用于处理数组。

.each返回最初提供的同一个数组:

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

.map从每个块调用的结果中返回一个新的数组:

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

当你使用map到一个散列,它隐式地把散列投到一个数组,所以你有

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

vs.each {…}只给出了[[d,[11,22]]和[33,44,55]的最后一个评估[11,22]中的[“f”,[ 33,44,55]]。 所以在最后join之前,你有

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

Array#每个方法返回相同的数组

 a = [1,2,3,4,5] a.object_id #70284994490700 b = a.each {|n| n + 2} pb #[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} pd #[3,4,5,6,7] d.object_id #70284994343620 <<---- it's different than c