rico_mac
rico_mac

Reputation: 888

dynamically create a hash in ruby

I am sure this is a question that has been asked before, but my research still hasn't led me to any conclusive answer. I am trying to create a standard key value pair in a loop.

The code below iterates as expected, but it is only storing the last value. I understand why, because I am overwriting the delivery_hash variable each time by use of the =. I tried using the shovel operator that I have used for arrays, but that didn't work.

def calculate_job_delivery_costs
  delivery_hash = {}
  DELIVERY_COST_SCOPES.each do |scope|
    delivery_hash = { scope => job_delivery_costs.send(scope).inject(0) { |total, item| (total + item.cost_per_unit * item.hour_count) * item.quantity } }
  end
  delivery_hash
end

my desired output is simply like this

"foo" => 234.32, 'bah' => 345.76, 'baz' => 33.87

Upvotes: 0

Views: 360

Answers (2)

Nick Veys
Nick Veys

Reputation: 23939

Well, one thing is just stop blowing away the variable, and use the hash you created in the first place:

def calculate_job_delivery_costs
  delivery_hash = {}
  DELIVERY_COST_SCOPES.each do |scope|
    delivery_hash[scope] = job_delivery_costs.send(scope).inject(0) do |total, item|
      (total + item.cost_per_unit * item.hour_count) * item.quantity
    end
  end
  delivery_hash
end

Or, simpler, just build the hash from the individual results:

def calculate_job_delivery_costs
  delivery_hashes = DELIVERY_COST_SCOPES.map do |scope|
    cost = job_delivery_costs.send(scope).inject(0) do |total, item|
      (total + item.cost_per_unit * item.hour_count) * item.quantity
    end
    [scope, cost]
  end
  Hash[delivery_hashes]
end

Upvotes: 3

joseramonc
joseramonc

Reputation: 1921

try with merge

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}

according to the ruby documentation: http://www.ruby-doc.org/core-2.1.2/Hash.html#method-i-merge

Upvotes: -1

Related Questions