将数组的哈希变成Ruby中的哈希数组

Jul*_*oux 11 ruby arrays hash

我们有以下数据结构:

{:a => ["val1", "val2"], :b => ["valb1", "valb2"], ...}
Run Code Online (Sandbox Code Playgroud)

我想把它变成

[{:a => "val1", :b => "valb1"}, {:a => "val2", :b => "valb2"}, ...]
Run Code Online (Sandbox Code Playgroud)

然后回到第一个表格.任何看起来很漂亮的人?

Avd*_*vdi 12

此解决方案适用于任意数量的值(val1,val2 ... valN):

{:a => ["val1", "val2"], :b => ["valb1", "valb2"]}.inject([]){|a, (k,vs)| 
  vs.each_with_index{|v,i| (a[i] ||= {})[k] = v} 
  a
}
# => [{:a=>"val1", :b=>"valb1"}, {:a=>"val2", :b=>"valb2"}]

[{:a=>"val1", :b=>"valb1"}, {:a=>"val2", :b=>"valb2"}].inject({}){|a, h| 
  h.each_pair{|k,v| (a[k] ||= []) << v}
  a
}
# => {:a=>["val1", "val2"], :b=>["valb1", "valb2"]}
Run Code Online (Sandbox Code Playgroud)


tok*_*and 7

使用函数方法(参见Enumerable):

hs = h.values.transpose.map { |vs| h.keys.zip(vs).to_h }
#=> [{:a=>"val1", :b=>"valb1"}, {:a=>"val2", :b=>"valb2"}]
Run Code Online (Sandbox Code Playgroud)

然后回来:

h_again = hs.first.keys.zip(hs.map(&:values).transpose).to_h
#=> {:a=>["val1", "val2"], :b=>["valb1", "valb2"]}
Run Code Online (Sandbox Code Playgroud)