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