Как суммировать свойства объектов в массиве в Ruby
Я понимаю, что для суммирования элементов массива в Ruby можно использовать метод inject, т. е.
array = [1,2,3,4,5];
puts array.inject(0, &:+)
но как суммировать свойства объектов в массиве объектов, например?
существует массив объектов, и каждый объект имеет свойство "cash", например. Поэтому я хочу суммировать их денежные остатки в один итог. Что-то вроде того...
array.cash.inject(0, &:+) # (but this doesn't work)
Я понимаю, что, вероятно, мог бы сделать новый массив, состоящий только из наличных денег собственности и суммировать это, но я ищите более чистый метод, если это возможно!
7 ответов
вы также можете попробовать:
array.sum(&:cash)
его ярлык для бизнеса inject и кажется более читаемым для меня.
http://api.rubyonrails.org/classes/Enumerable.html
#reduce
принимает блок (тег &:+
- это ярлык для создания proc / block, который делает +
). Это один из способов сделать то, что вы хотите:
array.reduce(0) { |sum, obj| sum + obj.cash }
самым кратким образом:
array.map(&:cash).sum
Если результирующий массив на карте имеет нулевые элементы:
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, то только сумма идентична inject:
array.map(&:cash).sum
и я бы предпочел версию блока:
array.sum { |a| a.cash }
потому что Proc от символа часто слишком ограничен (без параметров и т. д.).
(Должен Active_Support)