[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Something wrong with my hash of hash

Rassat Nicolas

10/29/2007 4:55:00 PM

I try to get a hash of hash to make some sort of counter (I have a set
of random pair and want to count the number of times they appear). I use
this code but even if I can access data, my hash seems empty (so each
and the others don't work):


h = Hash.new(Hash.new(0))
h["a"]["b"] += 1
h["a"]["b"] += 1
h["a"]["c"] += 1
p h["a"]["b"] => 2
p h["a"]["c"] => 1
p h.class => Hash
p h["a"].class => Hash
p h["a"]["b"].class => Fixnum
p h => {}


What's wrong?

Lars
--
Posted via http://www.ruby-....

5 Answers

Rassat Nicolas

10/29/2007 5:02:00 PM

0

Changing declaration by

h = Hash.new {|h,k| h[k] = Hash.new(0) }

makes things ok. What are the difference beetween the two declaration?

Lars

--
Posted via http://www.ruby-....

Gennady Bystritsky

10/29/2007 5:05:00 PM

0

list-bounce@example.com wrote:
> I try to get a hash of hash to make some sort of counter (I have a set
> of random pair and want to count the number of times they
> appear). I use
> this code but even if I can access data, my hash seems empty (so each
> and the others don't work):
>
>
> h = Hash.new(Hash.new(0))
> h["a"]["b"] += 1
> h["a"]["b"] += 1
> h["a"]["c"] += 1
> p h["a"]["b"] => 2
> p h["a"]["c"] => 1
> p h.class => Hash
> p h["a"].class => Hash
> p h["a"]["b"].class => Fixnum
> p h => {}
>
>
> What's wrong?
>
> Lars

Try this definition:

h = Hash.new { |h, k|
h[k] = Hash.new(0)
}

It will actually modify 'h' rather than simply returning and modifying the default value.

Gennady.

Rick DeNatale

10/29/2007 5:14:00 PM

0

On 10/29/07, Lars Ticot <nicolas.rassat@free.fr> wrote:
> I try to get a hash of hash to make some sort of counter (I have a set
> of random pair and want to count the number of times they appear). I use
> this code but even if I can access data, my hash seems empty (so each
> and the others don't work):
>
>
> h = Hash.new(Hash.new(0))
> h["a"]["b"] += 1
> h["a"]["b"] += 1
> h["a"]["c"] += 1
> p h["a"]["b"] => 2
> p h["a"]["c"] => 1
> p h.class => Hash
> p h["a"].class => Hash
> p h["a"]["b"].class => Fixnum
> p h => {}
>
>
> What's wrong?

You're using the wrong form of Hash.new for this use case.

Hash.new(default)

gives you a hash which simply returns default from [key] when key
doesn't exist, it leaves the hash itself alone.

You need to use a block

h = Hash.new {|h, k| h[k] = Hash.new(0)}
h["a"]["b"] += 1
h["a"]["b"] += 1
h["a"]["c"] += 1
h["a"]["b"] # => 2
h["a"]["c"] # => 1
h.class # => Hash
h # => {"a"=>{"b"=>2, "c"=>1}}
--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Sebastian Hungerecker

10/29/2007 6:26:00 PM

0

Lars Ticot wrote:
>> h = Hash.new(Hash.new(0))
> Changing declaration by
> h = Hash.new {|h,k| h[k] = Hash.new(0) }
> makes things ok. What are the difference beetween the two declaration?

There are two differences:
First: The first version executes "Hash.new(0)" once (before the outer
Hash.new is called, since parameters are evaluated before the actual method
call (obviously)) and stores the result as the default value. This means that
if you do something like h[:foo][:chunky] = "bacon" and h[:foo] has not been
assigned before, you will actually change the default value, so h[:bar]
[:chunky] will also be "bacon". The second version just stores the block and
executes it everytime a key that hasn't been assigned before is accessed.

Second: The second version has "h[k] =" in it, so it will not only return the
newly created hash, it will also store it in the outer hash. The first
version won't do that, which means that h will always appear as empty until
you do any actual assignments to it.


HTH,
Sebastian
--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Rassat Nicolas

10/29/2007 9:51:00 PM

0

Sebastian Hungerecker wrote:

> There are two differences:
[...]

Thanks all of you guys and especially Sebastian for the explanations.

Lars
--
Posted via http://www.ruby-....