3

ドキュメントには次のように記載されています。

enum#each_with_object :-

任意のオブジェクト obj を使用して各要素に対して指定されたブロックを反復し、obj を返します

enum#with_object:-

任意のオブジェクト obj を使用して各要素に対して指定されたブロックを反復し、obj を返します

しかし、両方の構成で以下を試したところ、1つは期待どおりの出力が得られましたが、他のものはそうではありませんでした。したがって、これら2つの構造には違いがあると思います。

使用する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>'

ここで失敗!

では、これら2つの方法の違いは何ですか?

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

eachEnumeratorオブジェクトを返します。

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

したがって、最初のケースでは、配列がEnumerator最初に変換されてから、で機能しwith_objectます。

2番目のケースを機能させたい場合は、配列を列挙子に変換する必要があります。.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 に答える