Reputation: 148
While executing a script, I need to delete multiple elements (these elements are not sequential) of an array. I will get my array and indexes while executing the script.
For example:
I may get an array and list of indexes like below:
my @array = qw(one two three four five six seven eight nine);
my @indexes = ( 2, 5, 7 );
I have below subroutine to do this:
sub splicen {
my $count = 0;
my $array_ref = shift @_;
croak "Not an ARRAY ref $array_ref in $0 \n"
if ref $array_ref ne 'ARRAY';
for (@_) {
my $index = $_ - $count;
splice @{$array_ref}, $index, 1;
$count++;
}
return $array_ref;
}
If I call my subroutine like below:
splicen(\@array , @indexes);
That works for me but:
Is there any better way to do this?
Upvotes: 7
Views: 1655
Reputation: 8542
If instead you splice from the end of the array, you won't have to maintain the offset $count
:
sub delete_elements {
my ( $array_ref, @indices ) = @_;
# Remove indexes from end of the array first
for ( sort { $b <=> $a } @indices ) {
splice @$array_ref, $_, 1;
}
}
Upvotes: 9
Reputation: 42421
Another way think about it is to build a new array rather than modifying the original:
my @array = qw(one two three four five size seven eight nine);
my @indexes = (2, 5, 7);
my %indexes = map { $_ => 1 } @indexes;
my @kept = map { $array[$_] } grep { ! exists $indexes{$_} } 0 .. $#array;
Upvotes: 1