I have a array of hashes like this.
[
{"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}
]
And I want this be like this.
[
{"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"}
]},
]
Hash should merge according to the equal event_id
values and there event can have many packages.
I want to know the easiest way to do this. Though I was able to do with many if and else s.
The simplest transformation that gives you the functional result you want is to use 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}]
#=> }
With this you can just do:
grouped.each do |event_id, packages|
# event_id is the actual value, like 336
# packages is an array of hashes from your original
end
If you really need exactly the format you described, then you can do this:
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"}
#=> ]}
#=> ]
The above runs through the groupings and transforms ("maps") each key/value pair to a custom hash, the contents of which have been munged according to your desires.
Finally I got it. For above input hash, I was manage to get a like this.
[{"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}
With using these methods. This is not the most accurate way. But it has done the the trick for me.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.