Something wrong with my hash of hash - RUBY

This is a discussion on Something wrong with my hash of hash - RUBY ; 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 ...

+ Reply to Thread
Results 1 to 6 of 6

Something wrong with my hash of hash

  1. Default Something wrong with my hash of hash

    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-forum.com/.


  2. Default Re: Something wrong with my hash of hash

    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-forum.com/.


  3. Default Re: Something wrong with my hash of hash

    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 =3D Hash.new(Hash.new(0))
    > h["a"]["b"] +=3D 1
    > h["a"]["b"] +=3D 1
    > h["a"]["c"] +=3D 1
    > p h["a"]["b"] =3D> 2
    > p h["a"]["c"] =3D> 1
    > p h.class =3D> Hash
    > p h["a"].class =3D> Hash
    > p h["a"]["b"].class =3D> Fixnum
    > p h =3D> {}
    >
    >
    > What's wrong?
    >
    > Lars


    Try this definition:

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

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

    Gennady.


  4. Default Re: Something wrong with my hash of hash

    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.denhaven2.com/


  5. Default Re: Something wrong with my hash of hash

    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


  6. Default Re: Something wrong with my hash of hash

    Sebastian Hungerecker wrote:

    > There are two differences:

    [...]

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

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


+ Reply to Thread

Similar Threads

  1. Re: Hash#keys, Hash#values order question
    By Application Development in forum RUBY
    Replies: 0
    Last Post: 08-23-2007, 08:21 AM
  2. Re: Hash#keys, Hash#values order question
    By Application Development in forum RUBY
    Replies: 0
    Last Post: 08-23-2007, 05:11 AM
  3. Hash#keys, Hash#values order question
    By Application Development in forum RUBY
    Replies: 0
    Last Post: 08-23-2007, 04:34 AM
  4. How to implement a hash whose key is another hash?
    By Application Development in forum RUBY
    Replies: 4
    Last Post: 08-20-2007, 07:29 PM
  5. Replies: 1
    Last Post: 08-26-2006, 07:48 PM