为什么Array#each返回一个具有相同元素的数组?

24
我正在学习Ruby中each的细节,并尝试了下面这行代码:
p [1,2,3,4,5].each { |element| el }

结果是一个数组。
[1,2,3,4,5]

为什么each的返回值是相同的数组?each难道不只是提供一个迭代的方法吗?或者each方法返回原始值只是常见做法吗?

Ruby API文档中说each {|item| block } → ary,因此Array类的each{block}方法确实返回self - mask8
3
这么做主要是为了方便。对于 Ruby 来说,返回原始数组基本上是一次“免费”的操作(否则它会返回 nil)。额外的好处是,如果需要,可以继续链式调用其他数组操作方法。 - Casper
一个小细节:如果没有块存在,[1,2,3].each返回[1,2,3].to_enum(至少在Ruby 2.0中)。 - Cary Swoveland
4个回答

30

Array#each 方法返回调用它的 [array] 对象:块的结果被 丢弃。因此,如果原始数组没有任何 令人讨厌的 副作用,那么什么也不会改变。

或许你想使用 map 方法?

p [1,2,3,4,5].map { |i| i*i }

3
我并没有试图使用 map,只是想知道为什么返回值是相同的数组。但你已经证实它只是返回相同的对象。 - Jeff Storey

5
如果您希望出于某种原因抑制输出(例如在控制台调试),以下是实现方法。
  [1,2,3,4,5].each do |nr|
    puts nr.inspect
  end;nil

6
哦我的天啊,“end;nil”就是我一生都在寻找的东西!!! - Andrew
1
基本上 end;nil 和在 end 后面写 return nil 是一样的。return 可以省略,因为 Ruby 方法总是返回最后一个语句。 - Cadoiz
当然,在真实的代码中这是毫无意义的。但很多时候,返回值会破坏控制台的输出。就像在我的例子中,你想要看到输出结果。 - Markus Andreas

4

Array#each

Array#each 的块形式返回原始的 Array 对象。通常在块内部处理数组的每个元素时使用 #each。例如:

[1, 2, 3, 4, 5].each { |element| puts element }

这将打印出每个元素,但返回原始数组。您可以通过以下方式验证:

array = [1, 2, 3, 4, 5]
array.each { |element| element }.object_id === array.object_id
=> true

Array#map

如果您想返回一个数组,您需要使用Array#map或者它的同义词。#map的块形式会返回一个不同的Array对象。例如:

array.object_id
=> 25659920
array.map { |element| element }.object_id
=> 20546920
array.map { |element| element }.object_id === array.object_id
=> false

你通常会在想修改原始数组的副本时使用 #map,同时保留原始数组不变。

3

所有的方法都会返回某些内容,即使只是一个nil对象,也会返回一些东西。

最好返回原始对象而不是返回nil


3
没错,我只是觉得它应该是空值(Nil),尽管我应该更仔细地阅读文档。 - Jeff Storey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接