Ruby hash merge by comparing a value -


i have following array of hashes

[{:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>0},  {:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>450},  {:day=>"may 2015", :rent=>0, :bond=>750, :rentinadvance=>0},  {:day=>"jun 2015", :rent=>600, :bond=>0, :rentinadvance=>0},  {:day=>"jul 2015", :rent=>600, :bond=>0, :rentinadvance=>0},  {:day=>"dec 2015", :rent=>600, :bond=>0, :rentinadvance=>0}] 

i need merge record using day key value, expected result is

[{:day=>"may 2015", :rent=>0, :bond=>750, :rentinadvance=>450},  {:day=>"jun 2015", :rent=>600, :bond=>0, :rentinadvance=>0},  {:day=>"jul 2015", :rent=>600, :bond=>0, :rentinadvance=>0},  {:day=>"dec 2015", :rent=>600, :bond=>0, :rentinadvance=>0}] 

thanks in advance..

tldr:

data.group_by |d|   d[:day] end.values.map |days|   days.inject |a,b|     {       day: a[:day],       rent: a[:rent] + b[:rent],       bond: a[:bond] + b[:bond],       rentinadvance: a[:rentinadvance] + b[:rentinadvance]     }   end end 

explanation:

let's have data in data variable:

data = [{:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>0},         {:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>450},         {:day=>"may 2015", :rent=>0, :bond=>750, :rentinadvance=>0},         {:day=>"jun 2015", :rent=>600, :bond=>0, :rentinadvance=>0},         {:day=>"jul 2015", :rent=>600, :bond=>0, :rentinadvance=>0},         {:day=>"dec 2015", :rent=>600, :bond=>0, :rentinadvance=>0}] 

then can group (group_by) array :day value,

grouped_data = data.group_by |d|   d[:day] end  # {"may 2015"=> #   [{:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>0}, #    {:day=>"may 2015", :rent=>0, :bond=>0, :rentinadvance=>450}, #    {:day=>"may 2015", :rent=>0, :bond=>750, :rentinadvance=>0}], #  "jun 2015"=>[{:day=>"jun 2015", :rent=>600, :bond=>0, :rentinadvance=>0}], #  "jul 2015"=>[{:day=>"jul 2015", :rent=>600, :bond=>0, :rentinadvance=>0}], #  "dec 2015"=>[{:day=>"dec 2015", :rent=>600, :bond=>0, :rentinadvance=>0}]} 

the key of resulting hash date, , value array of data-hashes. interested in values , map array of data-hashes single merged data-hash with:

merged_data = grouped_data.values.map |days|   days.inject |a,b|     {       day: a[:day],       rent: a[:rent] + b[:rent],       bond: a[:bond] + b[:bond],       rentinadvance: a[:rentinadvance] + b[:rentinadvance]     }   end end 

the inject merges 2 data-hashes (a , b) new hash. gives final result:

puts merged_data # {:day=>"may 2015", :rent=>0, :bond=>750, :rentinadvance=>450} # {:day=>"jun 2015", :rent=>600, :bond=>0, :rentinadvance=>0} # {:day=>"jul 2015", :rent=>600, :bond=>0, :rentinadvance=>0} # {:day=>"dec 2015", :rent=>600, :bond=>0, :rentinadvance=>0} 

ps: might read ruby documentation on methods, if you're not familiar them. i've added link each method used.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -