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

Fellow Monasterians:

I know how to find the size of an array: $# or $#$, but what if it's part of something like this:

$self->session->param('item' => [ 'indiv_conf', 'organ_conf', 'comp_co +nf' ] );

I want to iterate over each of the 3 elements in the array associated with 'item', but not sure how. Something like:

for ( 0..$#$self->session->param('item')) { print $self->session->param('item')->[$_].'\n'; }

But we know that's not right. Comments?


—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: Finding size of an array in an HoA
by shmem (Chancellor) on May 15, 2007 at 07:37 UTC
    Close:
    for (0.. $#{$self->session->param('item')} ) {

    gives you the indices into the array in $_ . But you might want

    for (@{$self->session->param('item')}) {

    to iterate over the elements themselves (in $_).

    You could as well take a reference to the array and use that:

    my $ary = $self->session->param('item'); for (@$ary) { ... }

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      Worked perfectly...a life saver. Thanks


      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot
Re: Finding size of an array in an HoA
by Fletch (Bishop) on May 15, 2007 at 12:47 UTC

    $#array is not the size of @array, it's the highest numbered index of @array. @array in scalar context is the size of the array.</pedant>

Re: Finding size of an array in an HoA
by Moron (Curate) on May 15, 2007 at 09:13 UTC
    Although I also take a reference for many situations (update: including this one :)) , your original example actually needs only braces around where an identifier name would go to work (update: at least functionally if not optimally) :
    for ( 0..$#{$self->session->param('item')} ) { print $self->session->param('item')->[$_]."\n"; }
    Other examples (of syntax) for using such braces for this:
    # to iterate the elements directly for my $conf ( @{$self->session->param('item')} ) { print "$conf\n"; }
    update: this one is also not optimal for the example because of its subroutine call being repeated a few times, (as shmem has meanwhile pointed out) but there are some more common situations where the for (;;) does optimise by avoiding a generated iteration array ... I often work with large A of Hs without subroutine calls and use this approach...
    for ( my $i; $i <= $#{$self ->session->param('item') }; $i++ ) { print $self -> session -> param('item') -> [$i ] . "\n"; }
    __________________________________________________________________________________

    ^M Free your mind!

      This snippet
      # typo here ------v :-) for ( 0..$#{$self->session->param('item'}} ) { print $self->session->param('item')->[$_]."\n"; }

      means that you have as many calls to session->param as there are elements in the referenced array (apart from the first to get its last index). While impact on speed and program size is minimal, it feels somehow convoluted; taking a reference and iterating over that is cheaper and feels cleaner.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        Actually I agree - getting a reference from a single call to the routine is obviously better in this particular case, but I thought it was worth at least exposing the correct version of the syntax that was being attempted.
        __________________________________________________________________________________

        ^M Free your mind!

Re: Finding size of an array in an HoA
by Anonymous Monk on May 15, 2007 at 09:47 UTC

    You can try this out if you are unsure of the size of the array

    #!/usr/bin/perl -w use strict; my %aoh = ( 'item' => ['indiv_conf', 'organ_conf', 'comp_conf','sfsfs' +,'afafa' ] ); foreach my $i ( keys %aoh) { if ($i eq'item') { foreach(@{$aoh{$i}}) { print "The item is $_\n"; } } }