似乎有很多方法可以在 Ruby 中遍历 Enumerable。each
, foreach
, 或 in collect
,map
或其他类似方法之间有什么区别吗?
或者有什么理由我不应该在某些情况下使用某些方法?
collect
/map
是等价的。它们的不同之处each
在于each
只为每个元素执行块,而collect
/map
返回一个数组,其中包含为每个元素调用块的结果。另一种说法可能是,each
期望对每个元素做一些事情,而map
期望对每个元素进行转换(将其映射到其他东西上)。
您可以使用collect
或使用map
任何地方each
,并且您的代码仍然可以工作。但它的效率可能会稍低一些,因为它将结果收集在一个数组中,除非您的 Ruby 实现意识到它不必费心创建一个数组,因为它从未使用过。
使用each
代替map
or的另一个原因collect
是帮助任何阅读您的代码的人。如果我看到each
了,那我就可以了,我们将使用数据的每个元素来做一些事情。如果我看到map
了,那么我希望看到基于旧数据的重新映射创建新数据。
关于map
vs.collect
我想说这是一个偏好问题,但你应该选择一个并坚持下去以保持一致性。
Array#collect
(and 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]"
使用pry
and 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
方法不收集结果