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

Hash Values into Array

by halecommarachel (Sexton)
on Aug 16, 2013 at 20:20 UTC ( [id://1049783]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,
I have a hash reference that's about three levels deep, i.e. $info->{$os}->{$testcase}->{error}
I would like to create an array with all the 'error' values, for every $testcase and $os. How can I do this?
Thanks!

Replies are listed 'Best First'.
Re: Hash Values into Array
by McA (Priest) on Aug 16, 2013 at 20:55 UTC

    Hi,

    my @errors; for my $os (keys %$info) { for my $testcase (keys %{$info->{$os}}) { push @errors, $info->{$os}->{$testcase}->{error}; } }

    McA

Re: Hash Values into Array
by Laurent_R (Canon) on Aug 16, 2013 at 21:35 UTC

    Another solution, perhaps somewhat simpler, might be to use the values function, rather than the keys function. Something like this:

    for my $os (values %$info) { for my $testcase (values %$os) { push @errors, values %$testcase } }

    This should also work if you have several errors possible for one testcase, such as 'error1', 'error2', etc.

    Update: corrected the typos indicated by kcott.

      "for $my os (values %info) {"

      Two corrections:

      • Typo: $my os should be my $os
      • Datatype: %info should be %$info (to match OP's $info->{$os}...)

       

      "This should also work if you have several errors possible for one testcase, such as 'error1', 'error2', etc."

      You're manufacturing data that the OP hasn't specified or even hinted at. I don't think this is a good idea. Furthermore, you're not targeting the specific key (i.e. error) that the OP did specify; you are, in fact, targeting every key that exists. Consider this scenario (using your code, with the corrections shown above):

      $ perl -Mstrict -Mwarnings -le ' my $info = { win => { t1 => { error => "missing arg" }, t2 => { skipped => "no network" } }, nix => { t1 => { error => "wrong type" }, t2 => { success => 1 } } }; my @errors; for my $os (values %$info) { for my $testcase (values %$os) { push @errors, values %$testcase } } print for @errors; ' no network missing arg wrong type 1

      -- Ken

        You're manufacturing data that the OP hasn't specified or even hinted at. I don't think this is a good idea. Furthermore, you're not targeting the specific key (i.e. error) that the OP did specify; you are, in fact, targeting every key that exists.

        You're right, Ken, but the OP did not provide any data, so I made some assumptions about the contents of the data structure. I quickly populated a nested data structure and tested the solution under the Perl debugger. The idea was only to show that using the values function rather than the keys function saved some typing and made the solution somewhat simpler.

      ... an excellent observation.   ++ ...

Re: Hash Values into Array
by sundialsvc4 (Abbot) on Aug 16, 2013 at 21:31 UTC

    perhaps adding an if clause to the above:

    ... push @errors, $info->{$os}->{$testcase}->{error} if defined($info->{$os}->{$testcase}->{error});

    This would avoid pushing undef values onto that array.   Also consider if exists() instead.

Re: Hash Values into Array
by mhearse (Chaplain) on Aug 17, 2013 at 17:17 UTC
    use strict; use Data::Dumper; my %hash = ( 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', ); my @array = values %hash; print Dumper(\@array);

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-26 00:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found