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)
你的问题的答案是:
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)