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"]}

或者,如果您使用的是较旧的 ruby​​ (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

让我们看看一些函数式方法。这是一个常见的抽象,你可以在 Facets 中找到它为Enumerable#map_by

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

这种模式取代了繁琐的group_by++ mapHash

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

这个有。面对我的 ruby​​ 版本中没有 each_with_object 和我到达的一些 googleze

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

非常感谢塞尔吉奥让我沿着这条线思考

于 2013-01-24T20:53:00.080 回答