Rubyの配列要素を合計するために、injectメソッドを使用できることを理解しています。
array = [1,2,3,4,5];
puts array.inject(0, &:+)
しかし、オブジェクト配列内のオブジェクトのプロパティを合計するにはどうすればよいですか?
オブジェクトの配列があり、各オブジェクトには、たとえば、プロパティ「キャッシュ」があります。したがって、私は彼らの現金残高を合計して1つの合計にしたいと思います。何かのようなもの...
array.cash.inject(0, &:+) # (but this doesn't work)
おそらく財産キャッシュのみで構成される新しい配列を作成し、これを合計することができると思いますが、可能であれば、よりクリーンな方法を探しています!
array.map(&:cash).inject(0, &:+)
または
array.inject(0){|sum,e| sum + e.cash }
In Ruby on Railsまた試してみてください:
array.sum(&:cash)
注入ビジネスのショートカットであり、私にとっては読みやすいようです。
http://api.rubyonrails.org/classes/Enumerable.html
#reduce
はブロックを取ります(&:+
は、+
)。これはあなたがしたいことをする一つの方法です:
array.reduce(0) { |sum, obj| sum + obj.cash }
最も簡潔な方法:
array.map(&:cash).sum
マップの結果の配列にnilアイテムがある場合:
array.map(&:cash).compact.sum
初期注入を使用する必要はなく、プラス操作を短くすることができます
array.map(&:cash).inject(:+)
ここでいくつかの興味深いベンチマーク
array = Array.new(1000) { OpenStruct.new(property: Rand(1000)) }
Benchmark.ips do |x|
x.report('map.sum') { array.map(&:property).sum }
x.report('inject(0)') { array.inject(0) { |sum, x| sum + x.property } }
x.compare!
end
そして結果
Calculating -------------------------------------
map.sum 249.000 i/100ms
inject(0) 268.000 i/100ms
-------------------------------------------------
map.sum 2.947k (± 5.1%) i/s - 14.691k
inject(0) 3.089k (± 5.4%) i/s - 15.544k
Comparison:
inject(0): 3088.9 i/s
map.sum: 2947.5 i/s - 1.05x slower
ご覧のとおり、注入が少し速くなります
合計の開始値が0の場合、合計のみが注入と同じです。
array.map(&:cash).sum
そして、私はブロック版を好むでしょう:
array.sum { |a| a.cash }
多くの場合、Proc fromシンボルは制限が多すぎるためです(パラメーターがないなど)。
(Active_Supportが必要)