似乎有很多方法可以在Ruby中循环使用Enumerable。 each
,foreach
或collect
,map
或其他类似方法之间是否存在差异?
或者在某些情况下我不应该使用某些方法吗?
答案 0 :(得分:5)
collect
/ map
是等效的。它们与each
的不同之处在于each
仅为每个元素执行块,而collect
/ map
返回一个数组,其中包含为每个元素调用块的结果。另一种方法可能是,each
预计做每个元素,而map
期望转换每个元素(map把它带到其他东西上。)
您可以在使用collect
的任何地方map
或each
使用,您的代码仍可使用。但它的效率可能略低,因为它会在数组中收集结果,除非您的Ruby实现意识到它不必费心创建数组,因为它从未使用过。
使用each
代替map
或collect
的另一个原因是帮助任何人阅读您的代码。如果我看到each
那么我就可以了,我们即将使用数据的每个元素来做某事。如果我看到map
,那么基于旧数据的重新映射,我希望看到正在创建新数据。
关于map
与collect
,我会说这是一个偏好问题,但你应该选择一个并坚持下去以保持一致。
答案 1 :(得分:1)
Array#collect
(和Array#map
)根据块中传递的代码返回一个新数组。 Array#each
对数组的每个元素执行一个操作(由块定义)。
我会像这样使用collect
:
array = [1, 2, 3]
array2 = array.collect {|val| val + 1}
array.inspect # => "[1, 2, 3]"
array2.inspect # => "[2, 3, 4]"
each
就像这样:
array = [1, 2, 3]
array.each {|val| puts val + 1 }
# >> 2
# >> 3
# >> 4
array.inspect # => "[1, 2, 3]"
答案 2 :(得分:1)
使用pry
和Rubinus
(它更容易阅读ruby代码)自己看看
$ pry
[1] pry(main)> cd Enumerable
[2] pry(Enumerable):1> show-method collect
From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9
def collect
if block_given?
ary = []
each { |o| ary << yield(o) }
ary
else
to_a
end
end
[3] pry(Enumerable):1> show-method map
From: .../rbx-head/kernel/common/enumerable18.rb @ line 4:
Owner: Enumerable
Visibility: public
Number of lines: 9
def collect
if block_given?
ary = []
each { |o| ary << yield(o) }
ary
else
to_a
end
end
[4] pry(Enumerable):1>
所以不要这两个人。
map
和collect
遍历集合。对于每个对象,它执行您的块然后收集结果。 each
方法不收集结果