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을 통과해야 :

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

그것은 처음 시도했지만 초기화가 없었기 때문에 작동하지 않는 키/값 솔루션을 검색했습니다. 죽은 간단한 감사합니다. –

5

flat_map(&:values)으로 모든 해시 값을 가져온 다음 inject(:+)을 사용하여 합계 할 수 있습니다.

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

접근 방식이 작동하지 않는 이유는 분사

오히려 배열의 각 해시 각각의 쌍의 키/값보다 블록에 각 해시를 산출하는 것입니다. 당신이 당신의 솔루션을 유지하기 원한다면, 당신은 뭔가 싶어 : 당신이 inject에 인수를 지정하지 않으면

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

+1로,하지만이 같은 두 번째 조각을 써서 : | 메모, 시간'array.inject (0) {| 메모 + h [: lol]}'. 또한'inject (0, : +)'첫 번째. Althouth는 OP가 "lol"키만 원했을 것입니다 :'{{lol : 1}, {lol : 2}]. h : [lol]} .inject (0, : +)' – tokland

+0

': lol'이 당신이 신경 쓰는 유일한 키라고 가정합니다. –

+0

받아 들인 대답보다 조금 더 길지만 새로운 것을 배웠습니다 +1. –

4

에서 documentation

.inject 명시 적으로 메모에 대한 초기 값을 지정하지 않으면 해당 컬렉션의 첫 번째 요소가 사용됩니다 메모의 초기 값으로 사용합니다.

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

메모의 값은 숫자 대신 해시이다.

수정이

array.inject(0) {|memo, hash| memo + hash[:lol]} # => 3 
관련 문제