2013-09-25 4 views
4

해시 배열이있어 선택한 값을 합산하려고합니다. 나는 그 (것)들 전부 또는 그 (것)들의 1 개를 합계하는 방법 그러나 1 개 이상 열쇠를 선택하는 방법 아닙니다 합계하는 방법을 알고있다.루비 : 선택한 해시 값의 합계

예 :

[{"a"=>5, "b"=>10, "active"=>"yes"}, {"a"=>5, "b"=>10, "active"=>"no"}, {"a"=>5, "b"=>10, "action"=>"yes"}] 

내가 사용 그들 모두를 요약하면 :

t = h.inject{|memo, el| memo.merge(el){|k, old_v, new_v| old_v + new_v}} 
=> {"a"=>15, "b"=>30, "active"=>"yesnoyes"} # I do not want 'active' 

가 하나의 키를 요약하면, 내가 할 :

h.map{|x| x['a']}.reduce(:+) 
=> 15 

가 어떻게 합산 가야합니까 키 'a'와 'b'에 대한 값?

+0

| X | x [ 'a'] + x [ 'b']} .reduce (: +)'? –

+0

귀하의 코멘트에 대해 @kardeiz에게 감사드립니다. 그러나 그것은 45를 반환하고 있습니다. 나는 그것을 분명하게해야했습니다 ... 내가 원하는 것은 : { 'a'=> 15, 'b'=> 30} – Digger

답변

6

당신은 values_at 사용할 수 있습니다

hs = [{:a => 1, :b => 2, :c => ""}, {:a => 2, :b => 4, :c => ""}] 
keys = [:a, :b] 
hs.map { |h| h.values_at(*keys) }.inject { |a, v| a.zip(v).map { |xy| xy.compact.sum }} 
# => [3, 6] 

을 필요한 모든 키 값을 갖는 경우가 짧아집니다 :

hs.map { |h| h.values_at(*keys) }.inject { |a, v| a.zip(v).map(&:sum) } 
# => [3, 6] 

당신이 Hash 다시 원하는 경우 :

Hash[keys.zip(hs.map { |h| h.values_at(*keys) }.inject{ |a, v| a.zip(v).map(&:sum) })] 
# => {:a => 3, :b => 6} 
+0

'values_at'는 이것을위한 완벽한 출발점입니다. . +1 –

+1

Thanks @ VictorMoroz, 해시 예제가 매력처럼 작동했습니다. 거기서 무엇을하고 있는지 설명해 주시겠습니까? 다시 한 번 감사드립니다. – Digger

2

이것은 어떻습니까?

h = [{"a"=>5, "b"=>10, "active"=>"yes"}, {"a"=>5, "b"=>10, "active"=>"no"}, {"a"=>5, "b"=>10, "action"=>"yes"}] 
p h.map{|e| e.reject{|k,v| %w(active action).include? k } }.inject{|memo, el| memo.merge(el){|k, old_v, new_v| old_v + new_v}} 
# >> {"a"=>15, "b"=>30} 
3

을 단계별로

a.map { |h| h.values_at("a", "b") }.transpose.map { |v| v.inject(:+) } 
#=> [15, 30] 

단계 : 나는 이런 식으로 뭔가를 할 거라고 단지`h.map을 {하지 왜

a.map { |h| h.values_at("a", "b") } #=> [[5, 10], [5, 10], [5, 10]] 
.transpose       #=> [[5, 5, 5], [10, 10, 10]] 
.map { |v| v.inject(:+) }   #=> [15, 30] 
+1

Thanks @Stefan에게 감사드립니다. 반환 된 배열에 키를 추가하려면 어떻게해야합니까? 반환 할 것으로 예상됩니다. { 'a'=> 15, 'b'=> 30} – Digger

+0

해시 [keys.zip (값)]. '해시 [[ "a", "b"] .zip ([15, 30])]' – Stefan