2

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

3
  • 2
    map is an unfortunate name for a variable in Ruby... Commented Apr 16, 2011 at 11:43
  • yes maybe hashmap would be more appropriate Commented Apr 16, 2011 at 12:14
  • possible duplicate of Ruby method Array#<< not updating the array in hash Commented Apr 16, 2011 at 18:34

1 Answer 1

5

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)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.