Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

iterate through a hash with two keys

by fionbarr (Monk)
on Apr 29, 2013 at 17:32 UTC ( #1031265=perlquestion: print w/ replies, xml ) Need Help??
fionbarr has asked for the wisdom of the Perl Monks concerning the following question:

hi...I have a hash that looks like:
$hash{'a' .. 'h'}{$label} = $value;
I want to iterate through the 'a' ..'h' and print all the values keyed by $label

Comment on iterate through a hash with two keys
Download Code
Re: iterate through a hash with two keys
by MidLifeXis (Prior) on Apr 29, 2013 at 17:34 UTC

    What you are doing is trying to assign a value, but not correctly. To assign $value, you could do something like this...

    $hash{$_}{$label} = $value for 'a' .. 'h';
    To print the value, use print, printf, or say with the same type of a structure.

    --MidLifeXis

      I am using xml_writer and I want to do this: for ('a' .. 'c') { $xml_writer->dataElement("LastName" => $t{A}{LastName}); } where the hash was filled by $t{A}{LastName} = "Smith"

      Independent of your solution to fionbarr's question and his real intention, I have tried to correct his code in the following way:

      use strict; use warnings; my %hash; my $label = "label"; my $value = "value"; # this does not work !!! @hash{ 'a'..'h' } = ( { $label => $value } ) x 9; $hash{ 'a' }{ $label } = "newvalue"; print $hash{ 'b' }{ $label },"\n"; # is "newvalue" !!!

      This results in a structure where $hash{'a'} to $hash{'h'} all point to the same hash, so changing one changes all of them.

      Is there a way to have the x operator really create 9 independent hash refs? (If this is helpful here or not is a different question.)

      The following code works but is too cumbersome.

      use strict; use warnings; my %hash; my $label = "label"; my $value = "value"; # this works !!! @hash{ 'a'..'h' } = ( { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, { $label => $value }, ); $hash{ 'a' }{ $label } = "newvalue"; print $hash{ 'b' }{ $label },"\n"; # is "value" !!!

        map { { $label => $value } } 1 .. 9?

        What you are doing is creating the hashref, and duplicating the same hashref that number of times.

        --MidLifeXis

Re: iterate through a hash with two keys
by LanX (Canon) on Apr 29, 2013 at 17:36 UTC
    Not sure what you want ...

    ... if $label should be variable, try

     print $hash{$_}{$label} for keys %hash

    Update:

    or shorter

     print $_->{$label} for values %hash

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    errata

    s/values/keys/ in first expression

      I didn't ask the question properly. I want to print all the labels and values for each of 'a' .. 'h' the label is a variable. I am filling this hash like: $hash{a}{$label} = $value; where $label is a text string.
        > I didn't ask the question properly.

        indeed!

        > I want to print all the labels and values for each of a .. h

        DB<103> @hash{$_} = {x=>$x++,y=>$x++} for a..h => "" DB<112> while ( my ($k1,$v1) = each %hash ) { while ( my ($k2,$v2) = each %$v1 ) { print "$k1 - $k2 -$v2\n" } } e - y -25 e - x -24 a - y -17 a - x -16 d - y -23 d - x -22 ... # and so on

        But are you looking for Data::Dumper ?

        UPDATE

        DB<106> print Dumper \%hash $VAR1 = { 'e' => { 'y' => 9, 'x' => 8 }, 'a' => { 'y' => 1, 'x' => 0 }, 'd' => { 'y' => 7, 'x' => 6 }, 'c' => { 'y' => 5, 'x' => 4 }, ...

        FWIW I prefer Data::Dump or YAML, but Data::Dumper is core.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        ) interesting Module::Build::YAML was first released with perl 5.009004

        UPDATE YAML
        DB<106> use YAML::Tiny => 0 DB<107> Dump(\%hash) --- a: x: 16 y: 17 b: x: 18 y: 19 c: x: 20 y: 21 d: x: 22 y: 23 ...
        This may be what you want.
        use strict; use warnings; my $label1 = 'L1'; my $label2 = 'L2'; my %hash; @hash{'a' .. 'h'} = ( {$label1 => 1 }, {$label1 => 2 }, {$label2 => 3 }, {$label1 => 4 }, {$label2 => 5 }, {$label1 => 6 }, {$label2 => 7 }, {$label1 => 8 }, ); while ( my( $key,$subhash ) = each %hash) { print "$key: $subhash->{$label1}\n" if exists $subhash->{$label1}; }
        OUTPUT:
        a: 1 d: 4 h: 8 b: 2 f: 6
        Bill

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (9)
As of 2014-07-30 08:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (229 votes), past polls