2013-03-24 128 views
1

我有一个这样的哈希数组。考虑单个哈希键值合并哈希阵列

[ 
{"package_details"=>{"name"=>"Package3", "price"=>3000.0, "id"=>"281"},"event_id"=>336}, 
{"package_details"=>{"name"=>"2000/-", "price"=>2000.0, "id"=>"280"}, "event_id"=>337}, 
{"package_details"=>{"name"=>"Package1", "price"=>1000.0, "id"=>"282"},"event_id"=>337}, 
{"package_details"=>{"name"=>"Package2", "price"=>2000.0, "id"=>"283"},"event_id"=>337} 
] 

我想这是这样的。

[ 
    {"event_id"=>336, "package_details"=>[ 
    {"name"=>"Package3", "price"=>3000.0, "id"=>"281"} 
    ]}, 
    {"event_id"=>337, "package_details"=>[ 
    {"name"=>"2000/-", "price"=>2000.0, "id"=>"280"}, 
    {"name"=>"Package1", "price"=>1000.0, "id"=>"282"}, 
    {"name"=>"Package2", "price"=>2000.0, "id"=>"283"} 
    ]}, 
] 

哈希应根据平等event_id值合并有事件可以有很多包。

我想知道最简单的方法来做到这一点。虽然我能够处理很多if和else。

+0

-1没有像你说的那样的数据结构,也不可能创建你想要的东西。您仅使用表示哈希文字的'{',但似乎您拥有数组和散列组合。请修改您的问题以显示您拥有的实际数据。 (提示:'p my_data'将打印'.inspect'结果。) – Phrogz 2013-03-24 15:55:57

+0

我已经编辑了你的问题,并且我相信你实际拥有的数据结构(哈希数组),并将你想要的结构改变为有意义的结构散列数组,其中每个键中的一个键引用散列数组)。 – Phrogz 2013-03-24 16:16:26

+0

你有错误的外部散列语法。也许你需要将外部散列更改为数组? – 2013-03-24 08:53:27

回答

5

最简单的转换就是使用Enumerable#group_by

details = [ 
{"package_details"=>{"name"=>"Package3","price"=>3000.0,"id"=>"281"},"event_id"=>336}, 
{"package_details"=>{"name"=>"2000/-","price"=>2000.0,"id"=>"280"},"event_id"=>337}, 
{"package_details"=>{"name"=>"Package1","price"=>1000.0,"id"=>"282"},"event_id"=>337}, 
{"package_details"=>{"name"=>"Package2","price"=>2000.0,"id"=>"283"},"event_id"=>337} 
] 

grouped = details.group_by{ |d| d["event_id"] } 
#=> { 
#=> 336=>[ 
#=>  {"package_details"=>{"name"=>"Package3", "price"=>3000.0, "id"=>"281"}, "event_id"=>336}], 
#=> 337=>[ 
#=>  {"package_details"=>{"name"=>"2000/-", "price"=>2000.0, "id"=>"280"}, "event_id"=>337}, 
#=>  {"package_details"=>{"name"=>"Package1", "price"=>1000.0, "id"=>"282"}, "event_id"=>337}, 
#=>  {"package_details"=>{"name"=>"Package2", "price"=>2000.0, "id"=>"283"}, "event_id"=>337}] 
#=> } 

有了这个,你可以这样做:通过分组

transformed = details.group_by{ |d| d["event_id"] }.map do |event_id, hashes| 
    { 
    "event_id"=>event_id, 
    "package_details"=>hashes.map{ |h| h["package_details"] } 
    } 
end  
#=> [ 
#=> {"event_id"=>336, "package_details"=>[ 
#=>  {"name"=>"Package3", "price"=>3000.0, "id"=>"281"} 
#=> ]}, 
#=> {"event_id"=>337, "package_details"=>[ 
#=>  {"name"=>"2000/-", "price"=>2000.0, "id"=>"280"}, 
#=>  {"name"=>"Package1", "price"=>1000.0, "id"=>"282"}, 
#=>  {"name"=>"Package2", "price"=>2000.0, "id"=>"283"} 
#=> ]} 
#=> ] 

以上运行:

grouped.each do |event_id, packages| 
    # event_id is the actual value, like 336 
    # packages is an array of hashes from your original 
end 

如果你真的需要正是你所描述的格式,那么你可以这样做并将每个键/值对转换(“映射”)为自定义哈希,其内容已根据您的需求进行了调整。

+0

谢谢Phorogz。虽然我现在已经提交了代码,但是当我重新考虑时,我将更改为此方法。再次感谢。 – 2013-03-25 04:27:19

0

最后我明白了。对于上面的输入哈希,我设法得到这样一个。

[{"packages"=>[{"name"=>"Package3", "price"=>3000.0, "id"=>"281"}], "event_id"=>336}, {"packages"=>[{"name"=>"2000/-", "price"=>2000.0, "id"=>"280"}, {"name"=>"Package1", "price"=>1000.0, "id"=>"282"}, {"name"=>"Package2", "price"=>2000.0, "id"=>"283"}], "event_id"=>337} 

使用这些方法。这不是最准确的方法。但它已经为我做了诀窍。

event_id_array = Array.new 
events_with_packages = Array.new 
events.each.each do |event| 
event_id_array.push(event.id) 
end 
event_id_array.uniq!.each_with_index do |e_id, i| 
    events_with_packages[i] = Hash.new 
    events_with_packages[i]["event_id"] = e_id 
    events_with_packages[i]["packages"] = Array.new 
    events.each do |event| 
    tmp_event = Hash.new 
    if(event.id==e_id) 
     tmp_event["id"] = event[:ep_id] 
     tmp_event["price"] = event[:price] 
     tmp_event["name"] = event[:ep_name] 
     events_with_packages[i]["packages"].push(tmp_event) 
    end 
    end 
end 
events_with_packages # the answer 
+0

这不是正确的做法。 Phorogz已经展示了如何去做。但如果有人感兴趣,我会保留这一点。 – 2013-03-25 04:29:06