Ruby - Hash not storing keys

801 Views Asked by At

I have executed the following in irb:

irb(main):068:0* map = Hash.new(Array.new)
=> {}
irb(main):069:0> map["a"]
=> []
irb(main):070:0> map["a"].push("hello")
=> ["hello"]
irb(main):071:0> map["a"].push(1)
=> ["hello", 1]
irb(main):072:0> map.has_key?("a")
=> false
irb(main):073:0> map.keys
=> []
irb(main):074:0>

Why is it that once i have added key "a" to the hash it is not appearing in the result of Hash#keys?

Thanks

1

There are 1 best solutions below

0
On BEST ANSWER

The Problem

By calling

map["a"].push("hello")

you alter the Hash's default object. In fact, after that, every possible key will deliver "hello", but the key isn't really initialized. The hash will only know its default object, but you didn't tell it to "initialize" the key.

ruby-1.9.2-head :002 > map["a"].push("Hello")
 => ["Hello"] 
ruby-1.9.2-head :003 > map["a"]
 => ["Hello"] 
ruby-1.9.2-head :004 > map["b"]
 => ["Hello"] 
ruby-1.9.2-head :004 > map.keys
 => [] 

What you might want to do is specifically initialize the key:

ruby-1.9.2-head :008 > map["a"] = Array.new
 => [] 
ruby-1.9.2-head :009 > map.keys
 => ["a"]

But this isn't really what you want.

Solution:

This default behavior can be achieved by using the following method to initialize the hash:

map = Hash.new { |hash, key| hash[key] = Array.new }

For example:

ruby-1.9.2-head :010 > map = Hash.new { |hash, key| hash[key] = Array.new }
 => {} 
ruby-1.9.2-head :011 > map["a"]
 => [] 
ruby-1.9.2-head :012 > map["b"]
 => [] 
ruby-1.9.2-head :013 > map.keys
 => ["a", "b"] 

(I'm no Ruby expert, so if there are some suggestions please add a comment)