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

Hello Perl monks, I require your wisdom. I would like to access specific arrays that reside inside of a hash but only specific arrays not all of them.
#!/usr/bin/perl use strict; my %hash = ( one => 'd$\vic', two => 'd$\daqq', three => 'c$\lol', four => 'd$\bom', five => 'd$\eef', six => 'd$\ff\logs' ); my %hoa = ( "array a" => [ "dd1", "dd2", "dd3", "dd4" ], "array b" => [ "gg1", "gg2", "gg3", "gg4" ], "array c" => [ "cc1", "cc2", "cc3", "cc4" ] ); my $input = <STDIN>; chomp $input; if ((exists $hash{$input})) { foreach my $group(keys %hoa) { foreach (@{$hoa{$group}}) { if ($input = $_) { print "$input found in $group\n"; } } } }

Replies are listed 'Best First'.
Re: specific array in hash of arrays
by ikegami (Patriarch) on Oct 09, 2008 at 09:07 UTC

    Replace "keys %hoa" with the list of specific names.

    By the way, $input = $_ is wrong.
    $input = $_ is an assignment.
    $input == $_ is a numerical comparison.
    $input eq $_ is a string comparison.
    See perlop.

Re: specific array in hash of arrays
by kwn (Novice) on Oct 09, 2008 at 10:25 UTC
    Another thing that's got me confused is why this returns nothing.
    #!/usr/bin/perl use strict; my %hoa = ( "arraya" => [ "dd1", "dd2", "dd3", "dd4" ], "arrayb" => [ "gg1", "gg2", "gg3", "gg4" ], "arrayc" => [ "cc1", "cc2", "cc3", "cc4" ] ); my $input = <STDIN>; chomp $input; if ((exists $hoa{$input}) and $input eq (@{$hoa{arraya}})) { print (@{$hoa{arraya}}); }

      moritz explained, so what follows is a solution. Basically, comparing a single value against an array makes so sense. By using grep, the value can be compared against every element of the array.

      #!/usr/bin/perl use strict; use warnings; my %hoa = ( arraya => [qw( dd1 dd2 dd3 dd4 )], arrayb => [qw( gg1 gg2 gg3 gg4 )], arrayc => [qw( cc1 cc2 cc3 cc4 )], ); chomp( my $array_name = <STDIN> ); # e.g. arraya chomp( my $to_find = <STDIN> ); # e.g. dd2 if ( exists( $hoa{$array_name} ) && grep { $_ eq $to_find } @{$hoa{$array_name}} ) { print( @{$hoa{$array_name}}, "\n" ); }

        Though looking up a hash will often be better than doing a linear search along a list. For example:

        #!/usr/bin/perl use strict; use warnings; my %hoh = ( flasha => { dd1 => 1, dd2 => 2, dd3 => 3, dd4 => 4 }, flashb => { gg1 => 1, gg2 => 2, gg3 => 3, gg4 => 4 }, flashc => { cc1 => 1, cc2 => 2, cc3 => 3, cc4 => 4 }, ); for ([qw(flasha dd4)], [qw(glashz gg2)], [qw(flashc zz)], [qw(flashc c +c1)]) { my ($array_name, $to_find) = @$_ ; if (exists $hoh{$array_name}->{$to_find}) { print( "$array_name contains $to_find\n" ); } }
        noting that exists stops looking, without complaint, if $hoh{$array_name} doesn't exist.

        If the list is a trivial length, then List::Util::first at least stops looking when it gets a match.

        I don't know what you need to do having discovered the match... the above allows you to map "array name" and "to_find" to anything you like -- the numbers above are for illustration, only !

        If you're only interested in existence, then

        flasha => { map { ($_, undef) } qw(dd1 dd2 dd3 dd4) },
        will serve.

        I think you answered my question as I was writing it! Awesome thanks.
      To satisfy the first condition (exists $hoa{$input}) $input has to be any of arraya, arrayb, arrayc. To satisfy the second condition, $input has to be equal to whatever @{$hoa{arraya}} stringifies to, which is probably 4 (because it's an array in scalar context, giving you the number of items in the array).

      Since no string is both equal to array$something and to 4 at once, you'll never get output from that script.

        I see. Would it be possible then to change the second condition in order to make sure that;
        $input has to be equal to arraya or @{$hoa{arraya}}?
        After that I will also need to iterate over each value of arraya... Err another thing I was thinking about was that
        there might be a different way to grab a specific array that exists inside a hash. Lets say I have 50
        arrays inside my hash and I want to do something to each value of a specific array based on <STDIN>. I dont want
        to right out 50 elsif statements... please help!
Re: specific array in hash of arrays
by kwn (Novice) on Oct 09, 2008 at 17:08 UTC
    One more question because I'm stuck again. I'm trying to do an action
    for each element of the called upon array inside of the
    hash. So what I think I need to do is a for loop but its not
    working... My perl cookbook is on the way, I promise but in
    the meantime I need monk power. Thanks.