这个数组有很多数据,我需要删除其中两个元素。
下面是我正在使用的代码片段:
my @array = (1,2,3,4,5,5,6,5,4,9);
my $element_omitted = 5;
@array = grep { $_ != $element_omitted } @array;
如果您已经知道要删除的元素的索引,可以使用splice。
如果您正在搜索,可以使用Grep。
如果您需要频繁进行此操作,则保持数组排序后,可以更好地提高性能,因为可以使用二分查找来找到所需的索引。
如果在您的上下文中有意义,您可能希望考虑使用“魔法值”来代替删除记录,以节省数据移动 - 例如将已删除的元素设置为undef。 当然,这也有其自身的问题(如果您需要知道“活动”元素的数量,您需要单独跟踪等),但根据您的应用程序可能值得一试。
编辑 实际上现在我再看一眼--不要使用上面的grep代码。 找到要删除的元素的索引,然后使用splice删除它会更有效率(您现在的代码会积累所有不匹配的结果..)
my $index = 0;
$index++ until $arr[$index] eq 'foo';
splice(@arr, $index, 1);
这将删除第一次出现的内容。 删除所有出现的内容也非常类似,只是您需要在一个步骤中获取所有索引:
my @del_indexes = grep { $arr[$_] eq 'foo' } 0..$#arr;
剩下的部分留给读者自己练习--记住,当你使用splice函数时,数组会发生变化!
编辑2 John Siracusa正确指出我在示例中有一个错误..已修复,对此感到抱歉。
my ($index) = grep { $arr[$_] eq 'foo' } 0..$#arr; if (defined $index) {splice(@arr, $index, 1); }
- 对于第一个匹配 - Reflectivesplice会按索引从数组中删除一个或多个元素。在您的示例中可以使用grep来搜索和删除。
你可以简单地这样做:
my $input_Color = 'Green';
my @array = qw(Red Blue Green Yellow Black);
@array = grep {!/$input_Color/} @array;
print "@array";
您是否经常需要执行此操作?如果是,您可能需要考虑使用不同的数据结构。每次都要搜索整个数组可能会非常耗时,特别是对于大型数组。如果速度是一个问题,那么您可能需要考虑使用哈希表。
在您的示例中,键将是数字,而值将是该数字元素的计数。
my @arr = ...;
# run through each item.
my @indicesToKeep = grep { $arr[$_] ne 'foo' } 0..$#arr;
@arr = @arr[@indicesToKeep];
@arr = @arr[grep ...]
,我特别喜欢这种方式。虽然我不确定它的效率如何,但我会开始使用它,因为它肯定不会比其他解决方案更糟糕。 - soger如果你改变了
my @del_indexes = grep { $arr[$_] eq 'foo' } 0..$#arr;
to
my @del_indexes = reverse(grep { $arr[$_] eq 'foo' } 0..$#arr);
foreach $item (@del_indexes) {
splice (@arr,$item,1);
}
foreach $index ( @list_of_indexes_to_be_skiped ) {
undef($array[$index]);
}
@array = grep { defined($_) } @array;
这就是诀窍! 费德里科
grep
命令会将它们删除。 - Deannasplice
。 - brian d foy本文的其余部分记录了将元素的测试转换为splice
偏移量所遇到的困难,从而使答案更具完整性。
看看您必须经历的曲折过程,才能拥有一个高效(即一次通过)的算法,将列表项上的测试转换为索引。这并不直观。
sub array_remove ( \@& ) {
my ( $arr_ref, $test_block ) = @_;
my $sp_start = 0;
my $sp_len = 0;
for ( my $inx = 0; $inx <= $#$arr_ref; $inx++ ) {
local $_ = $arr_ref->[$inx];
next unless $test_block->( $_ );
if ( $sp_len > 0 && $inx > $sp_start + $sp_len ) {
splice( @$arr_ref, $sp_start, $sp_len );
$inx = $inx - $sp_len;
$sp_len = 0;
}
$sp_start = $inx if ++$sp_len == 1;
}
splice( @$arr_ref, $sp_start, $sp_len ) if $sp_len > 0;
return;
}
如果数组中存在“something”,则删除所有出现的内容。
根据SquareCog的答案:
my @arr = ('1','2','3','4','3','2', '3','4','3');
my @dix = grep { $arr[$_] eq '4' } 0..$#arr;
my $o = 0;
for (@dix) {
splice(@arr, $_-$o, 1);
$o++;
}
print join("\n", @arr);
@arr
中删除索引时,下一个正确的要删除的索引将是$_-current_loop_step
。
perl -le '@ar=(1 .. 20);@x=(8,10,3,17);$x=join("|",@x);@ar=grep{!/^(?:$x)$/o} @ar;print "@ar"'