2013-10-07 3 views
-2

루비 :검색 중첩 된 해시 값이 같은 중첩 된 해시를

{ 
    :a=>{ 
     :toto=>{ 
       :foo=>10, 
       :bar=>11, 
       :baz=>12 
       }, 
     :titi=>"a" 
    }, 
    :b=>{ 
     :toto=>{ 
       :foo=>31, 
       :bar=>45, 
       :baz=>78 
       }, 
     :titi=>"b" 
    } 
} 

내 목표는 모든 :baz 값을 요약하는 것입니다. 나는 루비에서 이것을 할 수있는 아름다운 방법이있을 것이라고 확신한다. 어떤 생각?

감사합니다.

답변

5

#inject은 배열과 해시 모두에서 작동하는 매우 강력한 방법입니다. 해시 값을 살펴보고 필요한 키를 합계에 합할 수 있습니다.

hash.inject(0) { |sum, (_,v)| sum += v[:toto][:baz] } # => 90 
1
h = { 
    :a=>{ 
     :toto=>{ 
       :foo=>10, 
       :bar=>11, 
       :baz=>12 
       }, 
     :titi=>"a" 
    }, 
    :b=>{ 
     :toto=>{ 
       :foo=>31, 
       :bar=>45, 
       :baz=>78 
       }, 
     :titi=>"b" 
    } 
} 

h.inject(0){|sum,(_,v)| sum +=v.fetch(:toto,{}).fetch(:baz,0)} 
+0

대단히 감사합니다. @arup – unknownbits

+0

@prashantsharma 감사합니다. .. :) –

0

이 방법에 관계없이 경로의 모든 :baz 요소를 찾는다.

h = { 
    :a=>{ 
    :toto=>{ 
     :foo=>10, 
     :bar=>11, 
     :baz=>12, 
    }, 
    :titi=>"a" 
    }, 
    :b=>{ 
    :toto=>{ 
     :foo=>31, 
     :bar=>45, 
     :baz=>78, 
    }, 
    :titi=>"b", 
    }, 
} 

def sum_baz(hash) 
    hash.values.reduce(0) do |memo, elem| 
    if elem.is_a?(Hash) 
     memo += sum_baz(elem) 
     memo += elem[:baz] if elem[:baz] 
    end 
    memo 
    end 
end 

sum_baz(h) # => 90 
관련 문제