次のような配列の配列があります。
[[1,"A"], [1,"B"], [2,"C"], [2,"D"]]
結果を次のようにハッシュに取得したいと思います。
1 => {results => ["A","B"]}, 2 => {results => ["C","D"]}
「group_by」メソッドを使用してみましたが、この形式にすることができませんでした。これを行う最も効率的な方法は何ですか?
何か案は?
これは、あなたの望むことですか?
irb(main):001:0> a=[[1,"A"], [1,"B"], [2,"C"], [2,"D"]]
=> [[1, "A"], [1, "B"], [2, "C"], [2, "D"]]
irb(main):002:0> h={}
=> {}
irb(main):003:0> a.each { |k,v| h[k] ||= []; h[k] << v }
=> [[1, "A"], [1, "B"], [2, "C"], [2, "D"]]
irb(main):004:0> h
=> {1=>["A", "B"], 2=>["C", "D"]}
または、「結果」キーを持つ hashtable のハッシュテーブルが本当に必要な場合:
irb(main):003:0> a.each { |k,v| h[k] ||= {}; h[k]['result'] ||= []; h[k]['result'] << v }
=> [[1, "A"], [1, "B"], [2, "C"], [2, "D"]]
irb(main):004:0> h
=> {1=>{"result"=>["A", "B"]}, 2=>{"result"=>["C", "D"]}}
a = [[1,"A"], [1,"B"], [2,"C"], [2,"D"]]
Hash[a.group_by(&:first).map{ |k, v| [k, {"results" => v.map(&:last)}]}]
内部の「結果」という言葉が必要な理由はわかりませんが、必要なものを取得する方法は次のとおりです。
the_list = [[1,"A"], [1,"B"], [2,"C"], [2,"D"]]
#=> [[1, "A"], [1, "B"], [2, "C"], [2, "D"]]
by_key = the_list.group_by(&:first)
#=> {1=>[[1, "A"], [1, "B"]], 2=>[[2, "C"], [2, "D"]]}
as_result_hash = by_key.map do |key, matches|
[key, {'results'=>matches.map(&:last) }]
end
#=> [[1, {"results"=>["A", "B"]}], [2, {"results"=>["C", "D"]}]]
final = Hash[*as_result_hash.flatten(1)]
#=> {1=>{"results"=>["A", "B"]}, 2=>{"results"=>["C", "D"]}}
group_by の基本的な使用方法は既に理解されているようです。何らかのキーでグループ化された一連の結果を取得できます。
次のステップは、これらの結果を必要な形式にマップすることです。これを行うには、by_key ディクショナリをマップし、元のキーとマップされた結果を返すだけです。
これは配列を返すので、それをHash[*array.flatten(1)]
辞書に戻すために使用します。
内部の「結果」が必要ない場合は、次のようにします。
as_result_hash = by_key.map do |key, matches|
[key, matches.map(&:last)]
end
#=> [[1, ["A", "B"]], [2, ["C", "D"]]]