一連のカテゴリとその値をハッシュのリストとして保存しています。
r = [{:A => :X}, {:A => :Y}, {:B => :X}, {:A => :X}, {:A => :Z}, {:A => :X},
{:A => :X}, {:B => :Z}, {:C => :X}, {:C => :Y}, {:B => :X}, {:C => :Y},
{:C => :Y}]
次のようなハッシュとして、各値のカウントとそのカテゴリを取得したいと思います。
{:A => {:X => 4, :Y => 1, :Z => 1},
:B => {:X => 2, :Z => 1},
:C => {:X => 1, :Y => 3}}
どうすればこれを効率的に行うことができますか?
これが私がこれまでに持っているものです(一貫性のない値を返します):
r.reduce(Hash.new(Hash.new(0))) do |memo, x|
memo[x.keys.first][x.values.first] += 1
memo
end
最初に特定ののすべてのインスタンスのカウントを計算してから{:cat => :val}
、ハッシュを作成する必要がありますか?常に1を追加するのではなく、nil
ケースをチェックするために本文を減らして変更する(そして、場合はゼロを割り当てる)ために、別のベースケースを指定する必要がありますか?nil
編集:
結局、コードを変更し、以下のメソッドを使用して、ネストされたハッシュをよりクリーンな方法で実現しました。
r.map do |x|
[x.keys.first, x.values.last]
end.reduce({}) do |memo, x|
memo[x.first] = Hash.new(0) if memo[x.first].nil?
memo[x.first][x.last] += 1
memo
end