Prepare a hash so to identify indices efficiently, then index into the original array with it.
my %ref_index;
@ref_index{ @ind_toss } = ();
@arr_filt = @arr_orig[ grep { !exists $ref_index{$_} } (0..$#arr_orig) ];
Final @arr_filt
contains elements of the @arr_orig
at indices other than those in @ind_toss
.
See solution by ysth in this post for filtering array elements by another array in general.
Wrap it in a sub and run. Array with indices to exclude is @ind_toss
, original array is @arr_orig
.
use warnings;
use strict;
my @ind_toss = (1, 4, 5);
my @arr_orig = ('a', '1', 'b', 'c', '2', '6', 'd', 'e');
my @filtered = @{ filter_array_by_index(\@arr_orig, \@ind_toss) };
print "@filtered" . "\n";
sub filter_array_by_index {
my ($rarr, $rind) = @_;
my %ref_index;
@ref_index{ @$rind } = ();
return [ @$rarr[grep { !exists $ref_index{$_} } (0..$#$rarr)] ];
}
Prints
a b c d e
Notes
The return
from the sub, as hinted in comment by Oleg V. Volkov, can also be written as
return [ map { !exists $ref_index{$_} ? $rarr->[$_] : () } (0..$#$rarr) ];
This avoids construction of a list by grep
and a slice but rather indexes into the array conditionally.