9

如何使用grepmap删除数组中的元素或对数组的引用?我在使用splice从对数组的引用中删除一个或多个元素时遇到问题,并想看看是否grepmap可以为我提供更好的解决方案。

@removedElements = grep /test/, @array;
4

3 回答 3

10

你说的"array or reference array"好像是两种不同的东西。这令人困惑。

我假设既然你已经命名了你的数组@removedElements,那么你想问的是如何从中删除元素@array并将它们放入@removedElements

@removedElements = grep /test/, @array;   
@array           = grep ! /test/, @array;

对测试的简单否定将产生任一列表。你也可以做一个循环:

my (@removedElements, @rest);
for (@array) {
    if (/test/) {
        push @removedElements, $_;
    } else {
        push @rest, $_;
    }
}

这样做的好处是执行的检查更少。

为了使用splice,您需要跟踪索引,在这种情况下我不确定它是否值得。它肯定不会使您的代码更易于阅读。同样,我怀疑map它会比常规循环有用得多。

于 2012-05-29T00:58:43.517 回答
9

grep如果您知道要保留的元素,请使用。

my @keepers = grep /interesting/, @array;

相反,如果您有对数组的引用,则编写

my @keepers = grep /interesting/, @$arrayref;

请注意,这不会修改数组。

该过程与map. 给定一个拒绝元素的测试,写

my @keepers = map /do not want/ ? () : $_, @array;

颠倒测试的意义

my @keepers = map /interesting/ ? $_ : (), @array;
于 2012-05-29T01:32:17.477 回答
2

您可能还喜欢extract_by. List::UtilsBy它类似于 grep,只是它从传递的数组中删除项目。

use List::UtilsBy qw( extract_by );

# some values in @array

my @removed = extract_by { m/test/ } @array;

# Matching elements will now be removed from @array and appear in @removed.
于 2012-06-04T22:32:47.250 回答