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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11272929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:14:56  来源:igfitidea点击:

How to sum properties of the objects within an array in Ruby

rubyarraysobjectsuminject

提问by Spike Fitsch

I understand that in order to sum array elements in Ruby one can use the inject method, i.e.

我知道为了在 Ruby 中对数组元素求和,可以使用注入方法,即

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

But how do I sum the properties of objects within an object array e.g.?

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

There's an array of objects and each object has a property "cash" for example. So I want to sum their cash balances into one total. Something like...

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

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

I realise I could probably make a new array composed only of the property cash and sum this, but I'm looking for a cleaner method if possible!

我意识到我可能会创建一个仅由财产现金组成的新数组并将其求和,但如果可能的话,我正在寻找一种更清洁的方法!

回答by Yuri Barbashov

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

or

或者

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

回答by Hymanlin

In Ruby On Rails you might also try:

在 Ruby On Rails 中,您也可以尝试:

array.sum(&:cash)

array.sum(&:cash)

Its a shortcut for the inject business and seems more readable to me.
http://api.rubyonrails.org/classes/Enumerable.html

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

回答by Theo

#reducetakes a block (the &:+is a shortcut to create a proc/block that does +). This is one way of doing what you want:

#reduce接受一个块(这&:+是创建一个 proc/block 的快捷方式+)。这是做你想做的一种方式:

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

回答by vicocas

Most concise way:

最简洁的方法:

array.map(&:cash).sum

If the resulting array from the map has nil items:

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

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

回答by Christopher Oezbek

If start value for the summation is 0, then sum alone is identical to inject:

如果总和的起始值为 0,则 sum 本身与注入相同:

array.map(&:cash).sum

And I would prefer the block version:

我更喜欢块版本:

array.sum { |a| a.cash }

Because the Proc from symbol is often too limited (no parameters, etc.).

因为 Proc from 符号通常太有限(没有参数等)。

(Needs Active_Support)

(需要 Active_Support)

回答by mpospelov

Here some interesting benchmarks

这里有一些有趣的基准

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

And results

和结果

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

As you can see inject a little bit faster

正如你所看到的,注入速度要快一点

回答by megas

There's no need to use initial in inject and plus operation can be shorter

不需要在注入中使用初始值,并且加号操作可以更短

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