urjit on rails
urjit on rails

Reputation: 1893

Merge 2 Hash and create third new Hash in Ruby 2.6.3

I wish create a new hash from the following two hashes.

invoiced_data =
  {"Jan 2020"=>0, "Feb 2020"=>0, "Mar 2020"=>0, "Apr 2020"=>0,
   "May 2020"=>0, "Jun 2020"=>0, "Jul 2020"=>0.331027548e7,
   "Aug 2020"=>0.31668664e6, "Sep 2020"=>0, "Oct 2020"=>0,
   "Nov 2020"=>0, "Dec 2020"=>0}

payment_transaction_data =
  {"Jul 2020"=>400.0, "Aug 2020"=>26924.0}

All keys of the latter hash are keys of the former hash. The latter hash could be empty.

The hash I wish to construct has the same keys as invoiced_data. The values of those keys are hashes with keys :Invoiced_data and :payment_transaction_type. The values of :Invoiced_data are to to be the value of invoiced_data for the given key and the values of :payment_transaction_type are to be the value of payment_transaction_data for the given key, if the key is present, else zero. The result I need is as follows.

{"Jan 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "Feb 2020": {Invoiced_data: 0, payment_transaction_data: 0},         
 "Mar 2020": {Invoiced_data: 0, payment_transaction_data: 0},             
 "Apr 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "May 2020": {Invoiced_data: 0, payment_transaction_data: 0},         
 "Jun 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "Jul 2020": {Invoiced_data: 3310275.48, payment_transaction_data: 400.0},
 "Aug 2020": {Invoiced_data: 316686.64, payment_transaction_data: 26924.0},
 "Sep 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "Oct 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "Nov 2020": {Invoiced_data: 0, payment_transaction_data: 0},        
 "Dec 2020": {Invoiced_data: 0, payment_transaction_data: 0}}     

Upvotes: 0

Views: 130

Answers (4)

Cary Swoveland
Cary Swoveland

Reputation: 110645

You can do that as follows.

invoiced_data.each_with_object({}) { |(k,v),h| h[k] = { Invoiced_data: v,
  payment_transaction_data: payment_transaction_data.fetch(k,0) } }
  #=> {"Jan 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Feb 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Mar 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Apr 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "May 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Jun 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Jul 2020"=>{:Invoiced_data=>3310275.48,
  #                 :payment_transaction_data=>400.0},
  #    "Aug 2020"=>{:Invoiced_data=>316686.64,
  #                 :payment_transaction_data=>26924.0},
  #    "Sep 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Oct 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Nov 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0},
  #    "Dec 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}}

See Hash#fetch.

Upvotes: 0

user11350468
user11350468

Reputation: 1407

Try the below:

invoice_data = {"Jan 2020"=>0, "Feb 2020"=>0, "Mar 2020"=>0, "Apr 2020"=>0, "May 2020"=>0, "Jun 2020"=>0, "Jul 2020"=>0.331027548e7, "Aug 2020"=>0.31668664e6, "Sep 2020"=>0, "Oct 2020"=>0, "Nov 2020"=>0, "Dec 2020"=>0}
transaction_data = {"Jul 2020"=>400.0, "Aug 2020"=>26924.0}


{}.tap do |result|
  keys = invoice_data.keys + transaction_data.keys
  keys.uniq.each do |key|
    result[key] ||= {}
    result[key][:invoice_data] = invoice_data[key] || 0
    result[key][:transaction_data] = transaction_data[key] || 0
  end
end

Result:

 => {"Jan 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Feb 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Mar 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Apr 2020"=>{:invoice_data=>0, :transaction_data=>0}, "May 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Jun 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Jul 2020"=>{:invoice_data=>3310275.48, :transaction_data=>400.0}, "Aug 2020"=>{:invoice_data=>316686.64, :transaction_data=>26924.0}, "Sep 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Oct 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Nov 2020"=>{:invoice_data=>0, :transaction_data=>0}, "Dec 2020"=>{:invoice_data=>0, :transaction_data=>0}} 

Upvotes: 0

Salil
Salil

Reputation: 47462

invoiced_data = {'Jun 2020' => 0.3310273458e7, 'Jul 2020' => 0.331027548e7, 'Aug 2020' => 0.31668664e6}
payment_transaction_data = {'Jul 2020' => 400, 'Aug 2020' => 26924.0, 'Sep 2020' => 25834.0}

hash = {}
(invoiced_data.keys | payment_transaction_data.keys).each do |key|
  hash[key] = {}
  hash[key][:invoiced_data] = invoiced_data[key] || 0.0
  hash[key][:payment_transaction_data] = payment_transaction_data[key] || 0
end

then

puts hash # {"Jun 2020"=>{:invoiced_data=>3310273.458, :payment_transaction_data=>0},
 "Jul 2020"=>{:invoiced_data=>3310275.48, :payment_transaction_data=>400}, 
 "Aug 2020"=>{:invoiced_data=>316686.64, :payment_transaction_data=>26924.0}, 
 "Sep 2020"=>{:invoiced_data=>0.0, :payment_transaction_data=>25834.0}}

Upvotes: 0

Oleksandr Holubenko
Oleksandr Holubenko

Reputation: 4440

I'm pretty sure that it might be more optimized, but fast solution:

a
=> {"Jan 2020"=>0, "Feb 2020"=>0, "Mar 2020"=>0, "Apr 2020"=>0, "May 2020"=>0, "Jun 2020"=>0, "Jul 2020"=>3310275.48, "Aug 2020"=>316686.64, "Sep 2020"=>0, "Oct 2020"=>0, "Nov 2020"=>0, "Dec 2020"=>0}

b
=> {"Jul 2020"=>400.0, "Aug 2020"=>26924.0}

a.map do |k, v|
  [k, { Invoiced_data: v || 0, payment_transaction_data: b[k] || 0 }]
end.to_h
=> {"Jan 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Feb 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Mar 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Apr 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "May 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Jun 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Jul 2020"=>{:Invoiced_data=>3310275.48, :payment_transaction_data=>400.0}, "Aug 2020"=>{:Invoiced_data=>316686.64, :payment_transaction_data=>26924.0}, "Sep 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Oct 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Nov 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}, "Dec 2020"=>{:Invoiced_data=>0, :payment_transaction_data=>0}}

Upvotes: 1

Related Questions