Prepare a hash to efficiently determine indexes, and then index it into the source array.
my %ref_index; @ref_index{ @ind_toss } = (); @arr_filt = @arr_orig[ grep { !exists $ref_index{$_} } (0..$#arr_orig) ];
The @arr_filt
contains @arr_filt
elements at indices other than the indices in @ind_toss
.
See ysth's solution in this post for filtering array elements by another array as a whole.
Wrap it in a routine and run it. An array with indexes for exclusion is @ind_toss
, the 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)] ]; }
Print
abcde
Notes
return
from sub, as indicated in a comment by Oleg V. Volkov , can also be written as
return [ map { !exists $ref_index{$_} ? $rarr->[$_] : () } (0..$#$rarr) ];
This avoids constructing a grep
and slice list, but rather indexes it into an array conditionally.
source share