如何在Ruby中对数组中的对象的属性进行求和

我明白,为了总结Ruby中的数组元素,可以使用注入方法,即

array = [1,2,3,4,5]; puts array.inject(0, &:+) 

但是,我如何总结对象数组中的对象的属性?

有一个对象数组,每个对象都有一个属性“现金”,例如。 所以我想把他们的现金余额合计为一个。 就像是…

 array.cash.inject(0, &:+) # (but this doesn't work) 

我意识到我可以做一个新的数组只有财产现金和总结,但我正在寻找一个更干净的方法,如果可能的话!

 array.map(&:cash).inject(0, &:+) 

要么

 array.inject(0){|sum,e| sum + e.cash } 

你也可以尝试:

array.sum(&:cash)

它是注入业务的捷径,似乎对我更具可读性。
http://api.rubyonrails.org/classes/Enumerable.html

#reduce占用一个块( &:+是创build一个proc /块的快捷方式+ )。 这是做你想做的一种方式:

 array.reduce(0) { |sum, obj| sum + obj.cash } 

最简洁的方式:

 array.map(&:cash).sum 

如果来自地图的结果数组有零项:

 array.map(&:cash).compact.sum 

没有必要使用初始注入和加操作可以缩短

 array.map(&:cash).inject(:+) 

如果总和的起始值为0,则单独和注入相同:

 array.map(&:cash).sum 

我更喜欢块版本:

 array.sum { |a| a.cash } 

因为从符号Proc往往太有限(没有参数等)。

(需要Active_Support)

这里有一些有趣的基准

 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 

正如你所看到的,注入更快一点