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

Hi All,
  I use nested data strcutures quite a lot, and can easily end up with arrays, inside hashes, inside arrays, etc. Now when I'm looping through I like to use foreach as it makes the notation shorter. For example:-
my $ref; $ref = [ { "key1" => 'a', "key2" => 'b', }, { "key1" => 'c', "key2" => 'd', }, ]; foreach $hashref (@{$ref}) { print $hashref->{'key1'}; }#foreach
  Now I sometimes I want to know the array item number so I end up doing a for:-
for (my $item = 0; $item <= $#{$ref}; $item++) { print $item; print $ref->[$item]->{'key1'}; }#for
As you can see the print is much longer, when the data structure is more complex this can be a really big difference.
Is there a good way of getting the benefits of the notation in the first example while knowing the array item number. Is it safe to:-
my $item = 0; foreach $hashref (@{$ref}) { print $hashref->{'key1'}; $item++; }#foreach
Most the time the data is loading from files and I do not know how the foreach loop with deal with missing array items, such as:-
my $ref; $ref->[0]->{'key1'} = "a"; $ref->[5]->{'key1'} = "b"; my $item = 0; foreach $hashref (@{$ref}) { print $item; print $hashref->{'key1'}; $item++; }#foreach

Having written this, I realized I could answer my own questions simply by testing the final code example, perl does indeed fill in any missing array items producing the result I expected. I thought I'd post this anyway encase others have similar questions, or I'm sure there might be some interesting comments.

Lyle

Replies are listed 'Best First'.
Re: looping through array references
by GrandFather (Saint) on Feb 03, 2008 at 18:20 UTC

    Note that:

    for (my $item = 0; $item <= $#{$ref}; $item++) {

    is much better written:

    for my $item (0 .. $#{$ref}) {

    and you should always declare for loop variables in the loop header:

    foreach my $hashref (@{$ref}) {

    to avoid any reader's confusion about the scope of the variable.


    Perl is environmentally friendly - it saves trees
Re: looping through array references
by bobf (Monsignor) on Feb 03, 2008 at 20:31 UTC
Re: looping through array references
by hipowls (Curate) on Feb 03, 2008 at 20:17 UTC

    I use the following because it limits the scope of the two variables, $item and $hash_ref, to the loop where they are used.

    for my $item ( 0 .. $#{$ref} ) { $hash_ref = $ref->[$item]; print "$hash_ref->{'key1'}; }
    It also continues to work when you add extra code that includes a next or redo statement.

    Update fixed code thanks to johngg. Teach me to post without running it first;)

      I think there are a couple of problems with your code:

      • for my $item ( 0 .. @{$ref} ) is going to try to access an element beyond the end of the array. What you need here is $#{$ref}.

      • $hash_ref = $ref->{$item}; should be $hash_ref = $ref->[$item]; as you are dereferencing an array, not a hash

      Cheers,

      JohnGG