Marching two by two

Ovid on 2006-04-09T19:40:49

Well that was fun to write.

foreach my $i ( grep { !( $_ % 2 ) } 0 .. $#_ ) {
    ...
}


Re:

Aristotle on 2006-04-09T22:54:02

foreach my $i ( map { $_ * 2 } 0 .. $#_ / 2 ) {
    ...
}

?

Re:

Sidhekin on 2006-04-09T23:58:23

foreach my $i ( grep { ~$_ & 1 } 0 .. $#_ ) {
    ...
}
?

Re:

Aristotle on 2006-04-10T01:45:54

Same thing as Ovid’s, only painted green. Both his and yours make two to throw one away, whereas the approach I took does not.

Re:

Sidhekin on 2006-04-10T02:55:43

for ( my $i = 0 ; $i <= $#_ ; $i += 2 ) {
    ...
}
?

Readability

ChrisDolan on 2006-04-10T03:16:36

This one scores highest on readability. I assert that the other ones are too hard to understand and, thus, more likely to be buggy (i.e. off-by-one errors).

I think the best version is simply:

        for ( my $i = 0; $i @_; $i += 2 ) { ...
        }

It clearly selects even numbers and ends before just before the end of the array. The "@_" is more readable than "$#_", I say.

Re:Readability

Aristotle on 2006-04-10T08:01:55

foreach my $i ( 0 .. $#_ / 2 ) {
    my $j = $i * 2;
    ...
}

?

The most readable is actually if you can afford to destroy the array, which in Ovid’s case is probably true (because it is usually true for @_):

while( @_ ) {
    ...
    splice @_, 0, 2;
}