3

文档说:

enum#each_with_object :-

使用任意对象 obj 迭代每个元素的给定块,并返回 obj

enum#with_object:-

使用任意对象 obj 迭代每个元素的给定块,并返回 obj

但是当我在这两种结构上尝试以下操作时,一个给了我预期的输出,但其他的没有。所以我怀疑这两种结构之间存在差异。

使用each_with_object

%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
=> {"foo"=>"FOO", "bar"=>"BAR"}

在这里成功!

使用with_object

%w(foo bar).with_object({}) { |str, hsh| hsh[str] = str.upcase }
 => NoMethodError: undefined method `with_object' for ["foo", "bar"]:Array
    from (irb):1
    from C:/Ruby193/bin/irb:12:in `<main>'

这里失败了!

那么这两种方法有什么区别呢?

4

2 回答 2

5

with object仅适用于枚举器,这意味着您必须将其链接到返回一个的东西上。例如。

%w(foo bar).each.with_object({}) { |str, h| h[str] = str.upcase }

%w(foo bar).detect.with_object(obj) { ... }

所以,如果你不给它一个块,你可以调用with_object任何返回枚举器的东西(例如,,,,map... reduce)。这包括混合在Enumerable中的任何内容。detectfind_all

each_with_object本质上是each.with_object.

于 2013-02-03T12:09:19.103 回答
5

each返回一个枚举器对象。

%w(foo bar).each.class
=> Enumerator

因此,对于第一种情况,数组将Enumerator首先转换为,然后在with_object.

如果您希望第二种情况有效,则必须将数组转换为 Enumerator。您可以使用.to_enum.each.map来转换数组。

%w(foo bar).map.with_object({}) { |str, hsh| hsh[str] = str.upcase }
=> {"foo"=>"FOO", "bar"=>"BAR"}

更多细节:枚举器

于 2013-02-03T12:09:41.427 回答