in reply to A question of perlish elegance on array loop

it's not apparent why you need the index. if you really don't need the index, because you're processing the whole array anyway, then just do
foreach(@{$object_ref->{array_ref}}) { # loop code }
which provides all the values of the array one by one, without using an index.
the hardest line to type correctly is: stty erase ^H

Replies are listed 'Best First'.
Re^2: A question of perlish elegance on array loop
by ait (Hermit) on Nov 30, 2007 at 00:31 UTC
    lol

    I just knew that it would be questioned whether I needed the index or not and that is precisely why I added the comment at the last minute before posting the question!!!

    I use the reference to make the following code more readable. Here is the relevant code in context. endpoints is just a plain array of program paths, the wheels array is in the same order as endpoints array ( FYI is POEtry ;) )
    sub endpoint_dead { my ($kernel, $heap, $wheel_id) = @_[KERNEL, HEAP, ARG0]; $kernel->post('MAIN-Logger', 'alert', "Endpoint managed by wheel $ +wheel_id died\n"); my $self = $heap->{self}; # find the wheel and restart endpoint foreach(0..$#{@{$self->{endpoints}}}){ my $wheel = $self->{wheels}->[$_]; my $pname = $self->{endpoints}->[$_]; if($wheel->ID == $wheel_id){ [...]


    So, as you can see using the index is more elegant than something like:
    # find the wheel and restart endpoint my $i = 0; foreach(@{$self->{endpoints}){ my $pname = $_; my $wheel = $self->{wheels}->[$i]; [...] $i++; }
    Or even more elegant than the for construct in the original question.

      use List::MoreUtils qw( natatime zip ); ## ... my $iterator = natatime 2, zip @{ $self->{ endpoints } }, @{ $self->{ +wheels } }; while( my( $wheel, $pname ) = $iterator->next( ) ) { if( $wheel->ID == $wheel_id ) { frobnicate( $pname, $wheel ); } }

      Update: If only List::MoreUtils' zip behaved more like Ruby's Array#zip (which returns an Array of Arrays containing the merged items) . . . But then there wouldn't be a good Perl equivalent to auto-unwrapping the separate elements as the variables of the for loop.

      self.wheels.zip( self.endpoints ).each do | wheel, pname | frobnicate( wheel, pname ) end
      </c>

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

      If you really need the index, I find it much nicer to just keep a separate index variable.

      my $idx = 0; foreach my $thing( @{$object_ref->{array_ref}} ) { # do stuff with $thing $idx++; }
      nicely convoluted code :)
      now if there's no other reason....
      foreach(@{$self->{endpoints}}){ my $wheel = $self->{endpoints}->[$_]{wheels}; my $pname = $self->{endpoints}->[$_]; if($wheel->ID == $wheel_id){
      or some such
      or in general, if you find yourself accessing separate arrays/hashes with same index, it's probably a good case for rolling up the structure. data structures change quickly during early development, and these things sneak in when functionality is added.
      although there exist sometimes good reasons for keeping the structures separate.
      the hardest line to type correctly is: stty erase ^H