数组的Ruby散列

时间:2022-09-16 12:54:22

I have the following array

我有下面的数组。

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

I would like to convert this to a hash that looks like this

我想把它转换成这样的哈希

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

everything I have tried squashes the value.

我所尝试过的每一件事都在贬低它的价值。

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

I was thinking I could check to see if v[p[0]] is an array, but the variable isn't defined inside this block.

我想我可以检查一下v[0]是否为一个数组,但是变量在这个块中没有定义。

Is there a clean way to accomplish what I am looking for?

有没有一种干净的方式来完成我想要的?

3 个解决方案

#1


5  

Yeah, you have to do it yourself, I'm afraid.

是的,恐怕你得自己动手。

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

Or, if you're on older ruby (1.8.x):

或者,如果你使用的是旧ruby (1.8.x):

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

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

#2


4  

Let's see some functional approaches. This is a common abstraction, you can find it as Enumerable#map_by in Facets:

让我们看看一些功能方法。这是一个常见的抽象,您可以在facet中找到可枚举的#map_by:

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

This pattern replaces the cumbersome group_by + map + Hash:

此模式将替换笨重的group_by + map +散列:

Hash[hs.group_by(&:first).map { |k, gs| [k, gs.map(&:last)] }]
#=> {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}

#3


0  

this has it. in the face of not having each_with_object in my version of ruby and some googleze I arrived at

这它。在我的ruby版本中没有each_with_object,还有一些googleze。

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

mucho thanks to Sergio for getting me thinking along that line

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

#1


5  

Yeah, you have to do it yourself, I'm afraid.

是的,恐怕你得自己动手。

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

Or, if you're on older ruby (1.8.x):

或者,如果你使用的是旧ruby (1.8.x):

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

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

#2


4  

Let's see some functional approaches. This is a common abstraction, you can find it as Enumerable#map_by in Facets:

让我们看看一些功能方法。这是一个常见的抽象,您可以在facet中找到可枚举的#map_by:

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

This pattern replaces the cumbersome group_by + map + Hash:

此模式将替换笨重的group_by + map +散列:

Hash[hs.group_by(&:first).map { |k, gs| [k, gs.map(&:last)] }]
#=> {"kvm16"=>["one-415", "one-416"], "kvm5"=>["one-417"]}

#3


0  

this has it. in the face of not having each_with_object in my version of ruby and some googleze I arrived at

这它。在我的ruby版本中没有each_with_object,还有一些googleze。

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

mucho thanks to Sergio for getting me thinking along that line

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