2013-03-24 4 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"} 
    ]}, 
] 

Hash должны слиться в соответствии с равными event_id значений и там событие может иметь много пакетов.

Я хочу знать самый простой способ сделать это. Хотя я был в состоянии сделать со многими, если и еще.

+0

-1 Структура данных не похожа на то, что вы говорите, и у вас нет возможности создавать то, что вы хотите. Вы используете только '{', который обозначает литерал Hash, но кажется, что у вас есть комбинации массивов и хэшей. Измените свой вопрос, чтобы показать фактические данные. (Подсказка: 'p my_data' напечатает результат' .inspect'.) – Phrogz

+0

Я отредактировал ваш вопрос с структурой данных, я полагаю, что у вас есть (массив хэшей), и изменил вашу желаемую структуру на то, что имеет смысл (массив хэшей, где один из ключей в каждом ссылается на массив хэшей). – Phrogz

+0

У вас неправильный внешний синтаксис хэша. Может быть, вам нужно изменить внешний хэш на массив? –

ответ

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}] 
#=> } 

С этим вы можете просто сделать:

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

Если вам действительно нужен именно формат вы описали, то вы можете сделать это:

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"} 
#=> ]} 
#=> ] 

Вышеизложенные пробегает группировках и преобразует («карты») каждую пару ключ/значение в пользовательский хеш, содержимое которого было изменено в соответствии с вашими желаниями.

+0

Спасибо Phorogz. Хотя я уже совершил код, я перейду на этот метод, когда я перефакторинг. еще раз спасибо. –

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

Это неправильный способ сделать это. Погож показал, как это сделать. Но я буду держать это, если кто-то заинтересован. –

Смежные вопросы