2017-05-22 9 views
-1

皆さん。 は、私は同じ値が存在することができる。例えばルビーハッシュの同じ値の合計

{-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"} 

のハッシュを持っています。私の仕事は、値が等しいキーを合計することです。結果:

{51=>"a", -1=>"c", -38=>"ab"} 

どうすればいいですか?

hash.group_by{|key,val| val} 

ひどい結果が得られます。

+0

に置き換えることができるものの 'のために期待される結果{1 => "A"、2 => "A"、3 => "B"}'? – Stefan

+0

{3 => "a"、3 => "b"} – zOs0

+1

あなたの予期した結果は無効です。重複するキーはありません。 –

答えて

4
hash = {-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"} 

hash.reduce({}) do |memo, (k,v)| 
    memo[v] ||= 0 
    memo[v] += k 
    memo 
end.invert 

# => {51=>"a", -1=>"c", -38=>"ab"} 

reduceは - あなたがこの場合hashには、コレクションの値を反復することにより、新しい価値を構築することができます。詳細については、docsを参照してください。

invert - ハッシュのキーと値を入れ替えます。詳細はdocsをご覧ください。これを行うには

その他の方法:

hash.reduce(Hash.new(0)) { |memo, (k,v)| memo[v] += k; memo }.invert 
+1

2つのステートメントで 'reduce'の代わりに' each_with_object'を使うべきです。 –

+0

ええ、私は私の方法で立ち往生しています:) – Kris

+2

また、私はOPが欲しいと思っていることを知っていますが、同じ合計を持つ2つの文字列があれば 'invert'はデータを削除できます。 –

0
h = {-2=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"} 

その後、

h.group_by(&:last).each_with_object({}) { |(k,v),h| h[v.map(&:first).sum] = k } 
    #=> {51=>"a", -1=>"c", -38=>"ab"} 

が、それは和がユニークであることに依存しているとして、それは夢中になるでしょう。 (ハッシュが一意キーを持っていることを想起されたい。)-1=>"a"として

h = {-54=>"a", -1=>"c", 1=>"a", 3=>"a", 49=>"a", -43=>"ab", 5=>"ab"} 

次いで

h.group_by(&:last).each_with_object({}) { |(k,v),h| h[v.map(&:first).sum] = k } 
    #=> {-1=>"c", -38=>"ab"} 

を仮定は-1=<"c"によって上書きされます。これが欲しいとは思っていません。

配列内のhの内容を保存する方がよいでしょう:

a = [[-2, "a"], [-1, "c"], [-1, "a"], [49, "a"], [-43, "ab"], [5, "ab"]] 

(それは整数の重複する値を許可するよう - ここ-1)、その後

a.group_by(&:last).each_with_object({}) { |(e,ar),h| h[e] = ar.map(&:first).sum } 
    #=> {"a"=>46, "c"=>-1, "ab"=>-38} 

注意を計算その(元の値はh

h.group_by(&:last) 
    #=> {"a"=>[[-2, "a"], [1, "a"], [3, "a"], [49, "a"]], 
    # "c"=>[[-1, "c"]], "ab"=>[[-43, "ab"], [5, "ab"]]} 

v.map(&:first).sum

v.reduce(0) { |t,(n,_)| t+n } 
関連する問題