2012-06-18 6 views
0

У меня есть рубин хэш, как этотрубин хэш группы по идентификатору и выполнять сумму на сумму

 
[{user_id: 3, purchase: {amount: 2, type_id:3, name:"chocolate"}, 
{user_id: 4, purchase: {amount: 1, type_id:3, name: "chocolate"}, 
{user_id: 5, purchase: {amount: 10, type_id:4, name: "penny-candy"}] 

Я хочу взять массив и объединить в TYPE_ID, обобщать суммы, подключение пользователя к суммы, поэтому конечным результатом будет

 
[{type_id: 3, name: "chocolate", total_amounts:3, user_purchases[{user_id:3, amount:2},user_id:4,amount:1}], 
{type_id:4, name: "penny-candy", total_amounts: 10, [{user_id:5,amount:2}]}] 

Как я могу перейти от одного типа вывода к другому?

+0

Просто из любопытства, есть ли какие-либо конкретные причины для того, чтобы использовать массив? Вы можете использовать что-то вроде '{3 => {name:" chocolate ", total_amounts: 3, user_purchases [{user_id: 3, amount: 2}, user_id: 4, amount: 1}]}, {4 => {name: "penny-candy", total_amounts: 10, [{user_id: 5, amount: 2}]}} ', а это упростит ситуацию. – Amir

+0

@AmirF, он выходит из mysql, поэтому объект представлен как массив. Я не знаю, что есть другой способ сделать это. – pedalpete

ответ

1

Это проблема group_by. Я дам вам 2:

new_array = old_array.group_by{|x| x[:purchase][:type_id]}.values.map do |group| 
    {:type_id => group[0][:purchase][:type_id], :total_amounts => group.map{|g| g[:purchase][:amount]}.reduce(&:+)} 
end 

и оставить другой 2 в качестве упражнения

+0

очень красивый и чистый. Я полагал, что это была ошибка группировки, но она нуждалась в толчке. благодаря – pedalpete

0

Я бы первым упрощать:

old_arr = [ 
{user_id: 3, purchase: {amount: 2, type_id:3, name:"chocolate"}}, 
{user_id: 4, purchase: {amount: 1, type_id:3, name: "chocolate"}}, 
{user_id: 5, purchase: {amount: 10, type_id:4, name: "penny-candy"}}] 

intermediate_arr = old_arr.map{ |h| [h[:user_id], h[:purchase][:amount], h[:purchase][:type_id], h[:purchase][:name]]} 

Это создает следующий массив:

[[3, 2, 3, "chocolate"], [4, 1, 3, "chocolate"], [5, 10, 4, "penny-candy"]] 

Теперь вы можете отформатировать ее так, как вы хотите. Я решил отформатировать это следующим образом:

new_hash = {} 
intermediate_arr.each do |arr| 
    if new_hash[arr[2]] 
    new_hash[arr[2]][:purchase] += [{user_id: arr[0], amount: arr[1]}] 
    else 
    new_hash[arr[2]] = {name: arr[3], purchase: [{user_id: arr[0], amount: arr[1]}]} 
    end 
end 

Отдает:

{3=>{:name=>"chocolate", :purchase=>[{:user_id=>3, :amount=>2}, {:user_id=>4, :amount=>1}]}, 4=>{:name=>"penny-candy", :purchase=>[{:user_id=>5, :amount=>10}]}} 
Смежные вопросы