Hash of hashes by default

I want a Hash of Hashes. Furthermore, I want it so that if a key for
the first has does not exist, the default value is a new hash. It's
simple enough to do a has_key? on a hash to see if it already exists,
but it seems like there might be a trick to it that I'm not aware of.

So, instead of

foo = Hash.new

mylist.each do |ii|
  anotherlist.each do |jj|
    if foo.has_key?( ii )
        foo[ii][jj] = "hello world"
    else
        foo[ii] = { jj => "hello world" }
    end
  end
end

I can do:

mylist.each do |ii|
  anotherlist.each do |jj|
      foo[ii][jj] = "hello world"
end
end

Any suggestions?

irb(main):001:0> foo = Hash.new { |hash, key| hash[key] = Hash.new }
=> {}
irb(main):002:0> foo["ii"]["jj"] = "Hello World."
=> "Hello World."
irb(main):003:0> foo["ii"]
=> {"jj"=>"Hello World."}
irb(main):004:0> foo["ii"]["jj"]
=> "Hello World."

Hope that helps.

James Edward Gray II

···

On Jun 16, 2005, at 11:07 AM, Belorion wrote:

I want a Hash of Hashes. Furthermore, I want it so that if a key for
the first has does not exist, the default value is a new hash.

An infinite variation of this is a two liner.

  hinit = proc { |hash, key| hash[key] = Hash.new(&hinit) }
  foo = Hash.new(&hinit)

  foo["ii"]["jj"]["kk"] = "Hi, James!"

  require 'pp'
  p foo

-austin

···

On 6/16/05, James Edward Gray II <james@grayproductions.net> wrote:

On Jun 16, 2005, at 11:07 AM, Belorion wrote:

I want a Hash of Hashes. Furthermore, I want it so that if a key
for the first has does not exist, the default value is a new
hash.

irb(main):001:0> foo = Hash.new { |hash, key| hash[key] = Hash.new }
=> {}
irb(main):002:0> foo["ii"]["jj"] = "Hello World."
=> "Hello World."
irb(main):003:0> foo["ii"]
=> {"jj"=> "Hello World."}
irb(main):004:0> foo["ii"]["jj"]
=> "Hello World."

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Aha! Perfect!

···

On 6/16/05, James Edward Gray II <james@grayproductions.net> wrote:

On Jun 16, 2005, at 11:07 AM, Belorion wrote:

> I want a Hash of Hashes. Furthermore, I want it so that if a key for
> the first has does not exist, the default value is a new hash.

irb(main):001:0> foo = Hash.new { |hash, key| hash[key] = Hash.new }
=> {}
irb(main):002:0> foo["ii"]["jj"] = "Hello World."
=> "Hello World."
irb(main):003:0> foo["ii"]
=> {"jj"=>"Hello World."}
irb(main):004:0> foo["ii"]["jj"]
=> "Hello World."

Hope that helps.