4

私は最近、この問題に遭遇しました:
私はいつも inject をそのように使用してきました ((0) 部分はオプションであり、省略できることを知っていました)

array = [13,23,13]
#=> [13, 23, 13]
array.inject(0) { |sum,i| sum+i }
#=> 49

偶然、私はあなたが使用できることを知りました:

array.inject(:+)
#=> 49
array.inject(:-)
#=> -23
array.inject(:*)
#=> 3887
array.inject(:/)
#=> 0

この問題についてグーグルで調べると、inject に関する素敵な記事が見つかりましたが、私が試したことについては言及されていません....
誰かが私に説明したり、私が今使用したこれらの inject コマンドについていくつかの情報を提供したりできますか?

4

1 に答える 1

6

ドキュメントからEnumerable#inject

... 代わりにシンボルを指定すると、コレクション内の各要素が memo の名前付きメソッドに渡されます。どちらの場合も、結果が memo の新しい値になります。反復の最後に、 memo の最終値がメソッドの戻り値になります。

memo の初期値を明示的に指定しない場合は、コレクションの最初の要素が memo の初期値として使用されます。

したがって、シンボルを指定すると、それはメソッド名として扱われ、上記のように memo を置き換えて、列挙可能なすべての要素でこのメソッドが呼び出されます。現在、数学演算子 (+-*/) は単なるメソッドであり、他には何もありません。これらの行は同じ結果を生成します。

13 + 23 # => 36
13.+(23) # => 36
13.send(:+, 23) # => 36

シンボルを渡すinjectreduce、3 番目の形式を使用してその演算子を要素に動的に適用すると、次のようになります。

[1,2,3].inject(:+) # => 6

この短縮形は、演算子以外のメソッドでも使用できます。

[{"a"=>1}, {"b"=>2}].inject(:merge) # => {"a"=>1, "b"=>2} 
于 2013-01-25T16:49:38.743 に答える