Kurt Peek
Kurt Peek

Reputation: 57471

Merging hashes in Ruby not working as intended

I'm trying to reproduce an example in a Ruby tutorial of merging two hashes. However, using the "merge" method does not have the desired effect. When I run the following script:

capitals={'New York' => 'Albany','California' => 'Sacramento'}
more_capitals={'Texas' => 'Austin', 'Alaska' => 'Fairbanks'}

capitals.merge(more_capitals)

capitals.each do |state,capital|
    puts "#{capital} is the capital of #{state}"
end

I get this result:

Albany is the capital of New York
Sacramento is the capital of California

(see also screen grab from repl.it below). I would however also expect the output to contain "Austin is the capital of Texas" and "Fairbanks is the capital of Alaska" if the merging of the "capitals" and "more_capitals" hashes were carried out correctly. Why is this not the case?

enter image description here

Upvotes: 0

Views: 2862

Answers (2)

Shiva
Shiva

Reputation: 12514

FYI, In addition to @Kristján's Answer,

Sometimes you might also encounter this situation and get astonished

 > capitals      = { 'New York' => 'Albany', 'California' => 'Sacramento'}
 > more_capitals = {:'New York' => 'Albany', 'Alaska' => 'Fairbanks'}
 > capitals.merge!(more_capitals)

and

capitals.each do |state,capital|
    puts "#{capital} is the capital of #{state}"
end

Output

Albany is the capital of New York
Sacramento is the capital of California
Albany is the capital of New York
Fairbanks is the capital of Alaska

Question

Why is merge! not working, its supposed to merge the values with same keys. i.e. New York

Explanation:
In Ruby's Hash, symbol, string, array, hash and Integer are considered as separate keys.

  > new_hash = {:'a' => 'value with string symbol as a key', 'a' => 'value with string as a key', [:a] => 'value with array as a key', {a: 'key_hash'} => 'value with hash a key'}

  > new_hash[:a]
 => "value with string symbol as a key" 
  > new_hash['a']
 => "value with string as a key" 
  > new_hash[[:a]]
 => "value with array as a key" 
  > new_hash[{a: 'key_hash'}]
 => "value with hash a key"

Upvotes: 3

Kristján
Kristján

Reputation: 18803

You're using the non-destructive version of merge, which returns a new Hash you need to assign and use.

new_capitals = capitals.merge(more_capitals)

Or, you can use merge!, which does it in place:

capitals.merge!(more_capitals)

Upvotes: 9

Related Questions