This uses the form of Hash::new that creates a creates an empty hash with a default value (here 0
). For a hash h
created that way, h[k]
returns the default value if the hash does not have a key k
. The hash is not modified.
countries = [{"Country"=>"Brazil", "Duration"=>"731/1 days"},
{"Country"=>"Argentina", "Duration"=>"123/1 days"},
{"Country"=>"Brazil", "Duration"=>"240/1 days"},
{"Country"=>"Argentina", "Duration"=>"260/1 days"}]
countries.each_with_object(Hash.new(0)) {|g,h| h[g["Country"]] += g["Duration"].to_i }.
map { |k,v| { "Country"=>k, "Duration"=>"#{v}/1 days" } }
#=> [{"Country"=>"Brazil", "Duration"=>"971/1 days"},
# {"Country"=>"Argentina", "Duration"=>"383/1 days"}]
The first hash passed to the block and assigned to the block variable g
.
g = {"Country"=>"Brazil", "Duration"=>"731/1 days"}
At this time h #=> {}
. We then compute
h[g["Country"]] += g["Duration"].to_i
#=> h["Brazil"] += "971/1 days".to_i
#=> h["Brazil"] = h["Brazil"] + 971
#=> h["Brazil"] = 0 + 971 # h["Brazil"]
See String#to_i for an explanation of why "971/1 days".to_i
returns 971
.
h["Brazil"]
on the right of the equality returns the default value of 0
because h
does not (yet) have a key "Brazil"
. Note that h["Brazil"]
on the right is syntactic sugar for h.[]("Brazil")
, whereas on the left it is syntactic sugar for h.[]=(h["Brazil"] + 97)
. It is Hash#[] that returns the default value when the hash does not have the given key. The remaining steps are similar.