2013-07-17 2 views
2

У меня есть массив хешей, каждый с ключом lol, который имеет целочисленное значение. Я хотел бы суммировать значения, всегда вводить инъекции, но теперь я получаю исключение:Использование инъекции с массивом хешей

array = [{lol: 1}, {lol: 2}] 
array.inject {|memo, (key, value)| memo + value} => 
NoMethodError: undefined method `+' for {:lol=>1}:Hash 
from (irb):26:in `block in irb_binding' 
from (irb):26:in `each' 
from (irb):26:in `inject' 
from (irb):26 

Por que?

ответ

2

Если не указать аргумент inject, значение для объекта памятки для первой итерации является первым элементом перечислимого , хэш в этом случае. Таким образом, вы просто должны пройти 0 в качестве аргумента inject:

array = [{lol: 1}, {lol: 2}] 
array.inject(0) { |sum, h| sum + h[:lol] } 
# => 3 
+0

Это была моя первая попытка, но без инициализации, поэтому я искал решение key/value, которое также не работало. Мертвое простое спасибо. –

5

Вы можете просто получить все значения хэш-функции с помощью flat_map(&:values), а затем использовать inject(:+), чтобы суммировать их.

[{lol: 1}, {lol: 2}].flat_map(&:values).inject(:+) 

Причина ваш подход не работает в том, что инъекционные собирается давать каждый хэш блока, а не каждой пары ключ/значение каждого хеш-массива. Если вы хотите, чтобы ваше решения, вы хотите что-то вроде:

array.map {|hash| hash.inject(0) {|memo, (key, value)| memo + value } }.inject(:+) 
+0

+1, но я бы написать второй фрагмент кода, как это: 'array.inject (0) {| памятка, ч | memo + h [: lol]} '. Также 'inject (0,: +)' для первого. Althouth OP, похоже, хочет только ключ «lol», поэтому: '[{lol: 1}, {lol: 2}]. Map {| h | h [: lol]} .inject (0,: +) ' – tokland

+0

Предполагая, что': lol' является единственным ключом, значение которого вам очень важно. –

+0

Немного длиннее принятого ответа, но я узнал что-то новое, +1. –

4

От .inject documentation

Если вы явно не указать начальное значение для памятки, то используется первый элемент коллекции как начальное значение памятки.

array.inject {|memo, (key, value)| memo + value} 

Значение для комментария хэш вместо числа.

исправить его

array.inject(0) {|memo, hash| memo + hash[:lol]} # => 3 
Смежные вопросы