Asked on #perl6
I am trying to remove elements from an array by preserving the indexes. Meaning if I delete first element, rest of the elements hold their original position. I wrote a function for it and you can find it here http://pastebin.com/Rfc32sh5 . I am just curious, is there any better way of doing this because Perl 6 is very rich in features and shortcuts.
The sub could be written as this
sub delete-idx( :@array!, :@idx! ) {
my @del = @array[@idx] :delete;
@array .= grep(*.defined);
return @del;
}
or this
sub delete-idx( :@array!, :@idx! ) {
gather for @idx -> $i {
take |@array.splice($i-$++, 1)
}
}
The benefit of the first one is that it's always 2 ops: a :delete
and a grep
, but the grep
can be expensive.
The second sub requires no storage var, and splice
has very good performance characteristics... However it requires one op (loop) per @idx
.
Either way, the result is this
my @a = [[1..4],[5..8],[9..12],[13..17]];
my @b = delete-idx( array => @a, idx => [0,2] );
say @a; # OUTPUT -> [[5 6 7 8] [13 14 15 16 17]]
say @b; # OUTPUT -> [[1 2 3 4] [9 10 11 12]]
FWIW, I've Benchmarked the two subs against a list of 8 lists, and the one using splice
was marginally faster for any less than 5 @idx
's.