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文档,因为map是Enumerable中的一个方法,而每个 ( 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