Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

how to dereference for the following hash of hash of arrays

by srins (Sexton)
on Nov 13, 2005 at 15:09 UTC ( [id://508107]=perlquestion: print w/replies, xml ) Need Help??

srins has asked for the wisdom of the Perl Monks concerning the following question:

Hi I need to deference the following hash of hash arrays to retrive all key value pairs,how to deference the following hash of hash arrays.
%component_tree = ( component1 => { (name => "command1", id=> "001"), (name => "command2", id=> "002"), (name => "command3", id=> "003"), (name => "command4", id=> "004") }, component2 => { (name => "command5", id=> "011"), (name => "command6", id=> "012"), (name => "command7", id=> "013"), (name => "command8", id=> "014") }, );
i need to print name,id,component1,component2.

Replies are listed 'Best First'.
Re: how to dereference for the following hash of hash of arrays
by Tanktalus (Canon) on Nov 13, 2005 at 15:34 UTC

    srins, the structure you have is actually a hash of hashes. You should try Data::Dumper to see a structure's layout whenever you're having trouble grasping it. In this case, the layout is like this:

    $VAR1 = { 'component1' => { 'name' => 'command4', 'id' => '004' }, 'component2' => { 'name' => 'command8', 'id' => '014' } };
    Now you're probably asking what the heck happened to the rest of your data. It got overwritten - a hash can only have a key once, and you've got 4 'name' keys and 4 'id' keys - only the last one is kept. What you probably want is a hash of arrays of hashes:
    %component_tree = ( component1 => [ { name => 'command1', id => '001' }, { name => 'command2', id => '002' }, { name => 'command3', id => '003' }, { name => 'command4', id => '004' }, ], component2 => [ { name => 'command5', id => '011' }, { name => 'command6', id => '012' }, { name => 'command7', id => '013' }, { name => 'command8', id => '014' }, ], );
    This keeps all your data intact. Next, you want to retrieve all the key/value pairs. Something like this:
    for my $comp (keys %component_tree) { print "Checking $comp...\n"; for my $data (@{$component_tree{$comp}}) { print " Found ", $data->{name}, " (id [", $data->{id}, "])\ +n"; } }
    This will produce output like this:
    Checking component1... Found command1 (id [001]) Found command2 (id [002]) Found command3 (id [003]) Found command4 (id [004]) Checking component2... Found command5 (id [011]) Found command6 (id [012]) Found command7 (id [013]) Found command8 (id [014])
    Note that the order of "Checking componentn..." is going to be random. It was just luck that this time they ended up in the same order that we inserted them. Count on that not being true as the hash grows. However, the order of commands is not luck - that is guaranteed since we're using an array.

Re: how to dereference for the following hash of hash of arrays
by tirwhan (Abbot) on Nov 13, 2005 at 15:27 UTC

    Your hash isn't being built the way you think it is (hint: put a use Data::Dumper at the head of the code and then print Dumper %component_tree to see for yourself). You probably want something like this:

    %component_tree = ( component1 => { command1 => "001", command2 => "002", } );
    etc. In which case you can get the command id for a command with e.g. $component_tree{component1}->{command1}

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: how to dereference for the following hash of hash of arrays
by pg (Canon) on Nov 13, 2005 at 18:50 UTC

    In this structure:

    { (name => "command1", id=> "001"), (name => "command2", id=> "002"), (name => "command3", id=> "003"), (name => "command4", id=> "004") }

    You were deceived by the visual efforts. It looks like that all four name/id pairs were independent, but actually not. They were all at the same flat level - eight key/value pairs. There is no difference between your structure and the following:

    { name => "command1", id=> "001", name => "command2", id=> "002", name => "command3", id=> "003", name => "command4", id=> "004" }

    Which hopefully helps you to see that, for example, name was assigned to some different values four times, and each time overwrites the previous one, thus it is left with the last assigned value "command4". So now we are saying that your original structure is the same as:

    { name => "command4", id=> "004" }

    But the following structure is different, and all four pairs of name/id can coexist:

    { [name => "command1", id=> "001"], [name => "command2", id=> "002"], [name => "command3", id=> "003"], [name => "command4", id=> "004"] }

      pg, I don't think that does the trick either. See my response. Try dumping that structure ... you'll get something like this:

      $VAR1 = { 'component1' => { 'ARRAY(0x816936c)' => [ 'name', 'command4', 'id', '004' ], 'ARRAY(0x813bf00)' => [ 'name', 'command2', 'id', '002' ] }, # ...
      Not what you want at all.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://508107]
Approved by jfroebe
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-19 15:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found