2

次の配列があります

a=[["kvm16", "one-415"], ["kvm16", "one-416"], ["kvm5", "one-417"]]

これを次のようなハッシュに変換したいと思います

{"kvm5"=>["one-417"], "kvm16"=>["one-417", "one-416"]}

私が試したことはすべて値を押しつぶします。

v=Hash[ a.collect do |p| [p[0], [ p[1] ] ] end ]
=> {"kvm5"=>["one-417"], "kvm16"=>["one-416"] }

v[p[0]] が配列かどうかを確認できると思っていましたが、このブロック内で変数が定義されていません。

私が探しているものを達成するためのきれいな方法はありますか?

4

3 に答える 3

5

ええ、あなたはそれを自分でしなければなりません、私は恐れています。

a = [["kvm16", "one-415"], ["kvm16", "one-416"], ["kvm5", "one-417"]]

h = a.each_with_object({}) do |(k, v), memo|
  (memo[k] ||= []) << v
end

h # => {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}

または、古いルビー(1.8.x)を使用している場合:

h = {}
a.each do |k, v|
  (h[k] ||= []) << v
end

h # => {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}
于 2013-01-24T20:26:34.103 に答える
4

いくつかの機能的アプローチを見てみましょう。これは一般的な抽象化であり、ファセットのEnumerable#map_byとして見つけることができます。

require 'facets'
hs.map_by { |k, v| [k, v] }
#=> {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}

このパターンは面倒なgroup_by+ map+を置き換えますHash:

Hash[hs.group_by(&:first).map { |k, gs| [k, gs.map(&:last)] }]
#=> {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}
于 2013-01-24T20:49:36.723 に答える
0

これは持っています。私のバージョンのルビーと私がたどり着いたグーグルゼに each_with_object がないことに直面して

{}.tap{ |h| items.each{ |item| h[item.id] = item } }
=> {"kvm5"=>["one-417"], "kvm16"=>["one-415", "one-416"]}

その線に沿って考えさせてくれたSergioに感謝します

于 2013-01-24T20:53:00.080 に答える