如何在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 }
#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
正如你所看到的,注入更快一点