What is the best way to exclude elements from an array by indexes in Perl?

I use the following code to exclude elements at @{$x} in indices at @{$index} . But I'm not sure if this is the most efficient way to implement this feature. Does anyone have a better way to do this.

 sub arrayexclude { my $x = shift; my $index = shift; my @keep_index = (0 .. (scalar(@{$x})-1)); delete @keep_index[@{$index}]; my $result=[]; for my $i (@keep_index) { if(defined $i) { push @{$result}, @{$x}[$i]; } } return $result; } 
+5
source share
3 answers

You do not need anything but an array of arrays , so I would not create sub for this.

 my @wanted = @array[@indices]; 

If you work with array references, the same recipe applies:

 my @wanted = @{$array}[@$indices]; 
+2
source

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.

+1
source

Just to clean up the zdim answer a bit (which is all the same):

 sub filter_array_by_index { my ( $rarr, $rind ) = @_; my %ref_index = map { $_ => 1 } @ind_toss; my @indices = grep { !$ref_index{$_} } (0..$#$rarr); return @{$rarr}[@indices]; } 
0
source

Source: https://habr.com/ru/post/1245056/


All Articles