该数组有很多数据,我需要删除两个元素.
以下是我正在使用的代码段,
my @array = (1,2,3,4,5,5,6,5,4,9); my $element_omitted = 5; @array = grep { $_ != $element_omitted } @array;
SquareCog.. 85
如果您已经知道要删除的元素的索引,请使用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;
剩下的作为阅读器的练习 - 请记住,当你拼接它时,阵列会发生变化!
Edit2 John Siracusa正确地指出我的例子中有一个错误..修复,抱歉.
如果您已经知道要删除的元素的索引,请使用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;
剩下的作为阅读器的练习 - 请记住,当你拼接它时,阵列会发生变化!
Edit2 John Siracusa正确地指出我的例子中有一个错误..修复,抱歉.
splice将通过索引删除数组元素.使用grep(如示例所示)进行搜索和删除.
这是你要做的很多事吗?如果是这样,您可能需要考虑不同的数据结构.Grep每次都会搜索整个阵列,对于大型阵列而言,这可能会非常昂贵.如果速度是个问题,那么您可能需要考虑使用Hash.
在您的示例中,键将是数字,值将是该数字的元素数.
如果你改变
my @del_indexes = grep { $arr[$_] eq 'foo' } 0..$#arr;
至
my @del_indexes = reverse(grep { $arr[$_] eq 'foo' } 0..$#arr);
这通过首先从数组的后面删除元素来避免阵列重新编号问题.将splice()放在foreach循环中可以清除@arr.相对简单易读......
foreach $item (@del_indexes) { splice (@arr,$item,1); }