如何将具有相同键的多个散列分组为散列数组

1 ruby arrays hash ruby-on-rails

从散列数组开始:

roles =[
 {:id=>1, :name=>"alpha", :gid=>1}, 
 {:id=>2, :name=>"beta", :gid=>2},   
 {:id=>3, :name=>"delta", :gid=>1}, 
 {:id=>4, :name=>"epsilon", :gid=>1}, 
 {:id=>5, :name=>"zeta", :gid=>3}
]
Run Code Online (Sandbox Code Playgroud)

我正在尝试获得另一种结构:

groups = [
 {:gid=>1, :roles=>[
    {:id=>1, :name=>"alpha"}, 
    {:id=>3, :name=>"delta"}, 
    {:id=>4, :name=>"epsilon"}]}, 
 {:gid=>2, :roles=>[{:id=>2, :name=>"beta"}]}, 
 {:gid=>3, :roles=>[{:id=>5, :name=>"zeta"}]}
]
Run Code Online (Sandbox Code Playgroud)

答案 - 所有答案输出相同..但是我必须投票给最快的一个..

time1 = Benchmark.measure do
 (1..10000).each do 
   roles.group_by { |e| e.slice(:gid) }.map{
     |k,v| k.merge(:roles => v.map { |e| e.except(:gid)}) }
 end
end
puts time1
user       system      total        real
1.150000   0.010000   1.160000 (  1.165781)

time2 = Benchmark.measure do
  (1..10000).each do
   roles.group_by{|el| el[:gid]}.map{|gid, els|
   {gid: gid, roles: els.map{ |el| { id: el[:id], name: el[:name]}}}}
   end
end
puts time2
user       system      total        real
0.270000   0.000000   0.270000 (  0.278286)

time3 = Benchmark.measure do
  (1..10000).each do
 roles.group_by{|h| h.delete(:gid)}.map{|k, v| {gid: k, roles: v}}
  end
end
puts time3
user       system      total        real
0.130000   0.000000   0.130000 (  0.134478)
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 5

你的问题的答案是:

gid = nil
h = [
  {:id=>1, :name=>"alpha", :gid=>1},
  {:id=>3, :name=>"delta", :gid=>1},
  {:id=>4, :name=>"epsilon", :gid=>1}
]
.each{|h| gid = h.delete(:gid)}
{gid: gid, roles: h}
Run Code Online (Sandbox Code Playgroud)

但整个事情可以这样完成:

roles.group_by{|h| h.delete(:gid)}.map{|k, v| {gid: k, roles: v}}
Run Code Online (Sandbox Code Playgroud)