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

Hey all,

I need to find the length of each variable-length array in a hash of arrays. My code atm is as follows:

foreach my $key (keys %valid) { for (my $i = 0; $i < $#[valid{$key]}; $i++) { print STDERR "$key: $valid{$key}[$i]\n"; } }

which doesn't work - Perl complains about $#[valid{$key}]. I can't seem to work round this - any advice would be a great help.

-- Foxcub

Replies are listed 'Best First'.
Re: Finding the length of an array in a hash of arrays
by Aristotle (Chancellor) on Aug 26, 2002 at 12:08 UTC

    Yes, because it is called $#{$valid{$key}}. To pick apart, $# gets the index of the last element of an array. The following curlies imply we want to get it from an arrayref. And inside them, we have $valid{$key} which is standard fare.

    However your approach is not good Perl. You're iterating over a list; you shouldn't do that with an index variable unless you really need the index number.

    foreach my $key (keys %valid) { foreach my $element (@{$valid{$key}}) { print STDERR "$key: $element\n"; } }

    And in this case, since you're not sorting the keys or otherwise in need of a specific order, you could use the more efficient each %hash function:

    while(my($key, $val) = each %valid) { foreach my $element (@$val) { print STDERR "$key: $element\n"; } }

    Makeshifts last the longest.

Re: Finding the length of an array in a hash of arrays
by thinker (Parson) on Aug 26, 2002 at 12:37 UTC
    Hi Foxcub,

    to get just the lengths of all the arrays in the hash, you could use
    #!/usr/bin/perl -w use strict; my %valid=( first => [1..8], second => [1..3], third => [1..6] ); for(keys %valid){ print "the length of \$valid{$_} is ", scalar @{$valid{$_}}, "\n"; }


    which produces
    the length of $valid{first} is 8 the length of $valid{third} is 6 the length of $valid{second} is 3
    on my machine.

    hope this helps

    thinker
Re: Finding the length of an array in a hash of arrays
by dreadpiratepeter (Priest) on Aug 26, 2002 at 12:20 UTC
    Try $#{$valid{$key}}.


    -pete
    "Pain heals. Chicks dig scars. Glory lasts forever."
      Beware though that this method will not return the number of elements in the array, only the last index position. If the array only has one element,  $#{$valid{$key}} will return 0.

      -- vek --