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

i have a hash where a particular value is an anonymous array
ex: $hash{"array"} = ['a','b','c','d','e']

i can refer to individual elements of the anon. array in a scalar context
ex: $hash{"array"}[2] = 'c';

but how can i count through a foreach loop for the length of that anonymous array?
ex: foreach $i (0..$#array)
where in the above example $#array would refer to the anon. array in $hash{"array"}

Replies are listed 'Best First'.
Re: referring to anonymous array in value of a hash in array context...
by BrowserUk (Patriarch) on Jul 08, 2004 at 01:04 UTC

    Unless the array is huge, it's easier to access the values directly through the for loop

    $hash{"array"} = ['a','b','c','d','e']; print for @{ $hash{ array } }; a b c d e

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

      Actually the size of the array shouldn't matter because when foreach gets a real array perl will be smart and won't expand things in place (it uses an iterator over the AV* behind the scenes which all happens in C underneath).

      $ perl -MBenchmark=timethese -e <<'EOC' $a = [ 0 ..5_000 ]; timethese( 2_000, { index => sub { for( my $i = 0; $i <= $#{ $a }; $i++ ) { $b = $a->[ +$i] } }, iterator => sub { for( @{ $a } ) { $b = $_ } } } ) EOC Benchmark: timing 2000 iterations of index, iterator... index: 27 wallclock secs (21.21 usr + 0.02 sys = 21.23 CPU) @ 94 +.21/s (n=2000) iterator: 6 wallclock secs ( 5.39 usr + 0.00 sys = 5.39 CPU) @ 37 +1.06/s (n=2000)
Re: referring to anonymous array in value of a hash in array context...
by davidj (Priest) on Jul 08, 2004 at 00:57 UTC
    This will do it:

    #!/usr/bin/perl use strict; my %hash; my $i; $hash{"array"} = ['a','b','c','d','e']; for ($i = 0; $i <= $#{ $hash{array} }; $i++) { print "$i = $hash{array}[$i]\n"; }

    davidj
Re: referring to anonymous array in value of a hash in array context...
by danielcid (Scribe) on Jul 08, 2004 at 13:58 UTC
    You could also do:
    foreach (@{$hash{"array"}})
            {
            print "$_\n";
            }
    
    []'s -DBC
Re: referring to anonymous array in value of a hash in array context...
by ihb (Deacon) on Jul 08, 2004 at 17:52 UTC

    Use $# as any other sigil. As you may or may not know, you can use ${...}, @{...}, %{...} etc when dereferecing, but often the curlies are redundant which is why you don't see them so often. In fact, $foo can be written as ${foo} (which is an often seen trick when interpolating $foo in string like "this${foo}that" where $foothat would be interpolated if the brackets weren't there).

    Anyway, in your case this means that you'd use $#{$hash{array}} and @{$hash{array}} to get the last element and the array itself, respectively.

    See the perlref manpage for more details. Good reading is also to be found in perlreftut, perllol and perldsc

    Hope I've helped,
    ihb