Array#each vs. Array #map

use*_*308 89 ruby arrays enumerable

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"
Run Code Online (Sandbox Code Playgroud)

唯一的区别是案例1使用vs.map,案例2使用vs.each.

这里发生了什么?

Oli*_*ves 171

Array#each 为数组的每个元素执行给定的块,然后返回数组本身.

Array#map 还为数组的每个元素执行给定的块,但返回一个新数组,其值是块的每次迭代的返回值.

示例:假设您已经定义了一个数组:

arr = ["tokyo", "london", "rio"]
Run Code Online (Sandbox Code Playgroud)

然后尝试执行each:

arr.each { |element| element.capitalize }
# => ["tokyo", "london", "rio"]
Run Code Online (Sandbox Code Playgroud)

请注意,返回值只是相同的数组.each块中的代码被执行,但不返回计算的值; 并且由于代码没有副作用,因此该示例不执行任何有用的工作.

相反,调用数组的map方法返回一个新数组,其元素是执行map块的每一轮的返回值:

arr.map { |element| element.capitalize }
# => ["Tokyo", "London", "Rio"]
Run Code Online (Sandbox Code Playgroud)

  • 理解的完美答案。只是......免责声明:如果过度使用映射函数的返回值,则可能会浪费大量内存。 (2认同)

Dig*_*oss 33

副作用是它增加了一些混乱的逆向工程相同.

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

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

什么map是返回一个数组,其中包含传递的块或命名方法的结果.例如:

    2.2.3 :001 > [:how, :now, :brown, :cow].map &:to_s
 => ["how", "now", "brown", "cow"]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我没有传递一个块,只是一个Symbol,但是class Symbol对象有一个to_proc方法,将导致:

[:how.to_s, :now.to_s, ...]
Run Code Online (Sandbox Code Playgroud)

顺便说一下,您可能很难找到文档,因为mapEnumerable中的一个方法,而每个(Enumerable模块所需的一个方法)是Array中的方法.

作为一个琐事说明:地图实施基于每个.


Rim*_*ima 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"]
Run Code Online (Sandbox Code Playgroud)

你看到地图返回,["map_a", "map_b", "map_c"]而每个只是迭代但返回原始数组:["a", "b", "c"].

因此,每个用于处理数组,而map用于处理已处理的数组.