3

似乎有很多方法可以在 Ruby 中遍历 Enumerable。each, foreach, 或 in collect,map或其他类似方法之间有什么区别吗?

或者有什么理由我不应该在某些情况下使用某些方法?

4

3 回答 3

6

collect/map是等价的。它们的不同之处each在于each只为每个元素执行块,而collect/map返回一个数组,其中包含为每个元素调用块的结果。另一种说法可能是,each期望对每个元素一些事情,而map期望对每个元素进行转换(将其映射到其他东西上)。

您可以使用collect或使用map任何地方each,并且您的代码仍然可以工作。但它的效率可能会稍低一些,因为它将结果收集在一个数组中,除非您的 Ruby 实现意识到它不必费心创建一个数组,因为它从未使用过。

使用each代替mapor的另一个原因collect是帮助任何阅读您的代码的人。如果我看到each了,那我就可以了,我们将使用数据的每个元素来做一些事情。如果我看到map了,那么我希望看到基于旧数据的重新映射创建新数据。

关于mapvs.collect我想说这是一个偏好问题,但你应该选择一个并坚持下去以保持一致性。

于 2013-04-05T22:12:40.560 回答
1

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]"
于 2013-04-05T22:10:06.117 回答
1

使用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>

所以不适合这两个。

mapcollect遍历一个集合。对于每个对象,它执行你的块然后收集结果。each方法不收集结果

于 2013-04-05T22:12:14.760 回答