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
Post a Comment