“each”,“foreach”,“collect”和“map”之间有什么区别?

时间:2013-04-05 22:03:16

标签: ruby loops enums iterator iteration

似乎有很多方法可以在Ruby中循环使用Enumerable。 eachforeachcollectmap或其他类似方法之间是否存在差异?

或者在某些情况下我不应该使用某些方法吗?

3 个答案:

答案 0 :(得分:5)

collect / map是等效的。它们与each的不同之处在于each仅为每个元素执行块,而collect / map返回一个数组,其中包含为每个元素调用块的结果。另一种方法可能是,each预计每个元素,而map期望转换每个元素(map把它带到其他东西上。)

您可以在使用collect的任何地方mapeach使用,您的代码仍可使用。但它的效率可能略低,因为它会在数组中收集结果,除非您的Ruby实现意识到它不必费心创建数组,因为它从未使用过。

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

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

答案 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)

使用pryRubinus(它更容易阅读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方法不收集结果