Skip to content

Instantly share code, notes, and snippets.

@0racle
Last active October 5, 2016 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0racle/abbc0d2f7c7e8110abbd987aacc7a5f8 to your computer and use it in GitHub Desktop.
Save 0racle/abbc0d2f7c7e8110abbd987aacc7a5f8 to your computer and use it in GitHub Desktop.
Delete Indexes

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment