in reply to Efficient array element deletion

On the other extreme of the spectrum, I could say
for (-$#array .. 0) { splice (@array,$_,1) if ($array[$_] =~ /^\#/) }

That doesn't do what you seem to think it does.   It starts with the second element of the array, iterates up to the last element of the array and finally ends with the first element of the array.   If you splice elements out of the array then the elements remaining will be moved and won't be removed by subsequent splices.

What you need to do is start at the last element of the array and iterate towards the first element:

for ( reverse 0 .. $#array ) { splice @array, $_, 1 if $array[ $_ ] =~ /^\#/; }

Replies are listed 'Best First'.
Re^2: Efficient array element deletion
by ikegami (Patriarch) on Dec 04, 2008 at 23:55 UTC

    for ( reverse 0 .. $#array ) flattens the list.
    for ( -@array .. -1 ) is better.

      for ( reverse 0 .. $#array ) flattens the list.for ( -@array .. -1 ) is better.

      Except I don't think that will work either.

      J:\> perl -le "@arr = ( 1 .. 10 ); print $arr[ $_ ] for -@arr .. -1;" 1 2 3 4 5 6 7 8 9 10 J:\>

      From the documentation (Range Operators, my emphasis): In list context, it returns a list of values counting (up by ones) from the left value to the right value so I don't think it can be persauded to decrement. So doing

      J:\> perl -le "@arr = ( 1 .. 10 ); print $arr[ $_ ] for -1 .. -@arr;" J:\>

      results in nothing useful.

      Cheers,

      JohnGG

        I thought you were referring to the off-by-one error, and didn't notice it also iterated backwards.

        Solutions:
        for ( -$#array..0 ) { ... $array[-$_] ... }
        for ( my $i=@array; $i--; ) { ... $array[$i] ... }