Arrays 在perl语言中,检查一个数组中的值,如果另一个数组中的每个值都存在,则将其删除

Arrays 在perl语言中,检查一个数组中的值,如果另一个数组中的每个值都存在,则将其删除,arrays,perl,Arrays,Perl,基本上,我有一个数组,比如说@badvalues 我有另一个数组,比如说@values 基本上,我想要这个: 对于@badvalues 查看它是否位于@values 如果是,请将其删除 最终,我应该得到一个数组@values,它不包含数组@badvalues中的任何元素,或者一个新数组@goodvalues,它包含@values中不是@badvalues元素的每个@values元素 我知道这听起来很简单,也许是因为我累了,但在四处搜索时,我似乎找不到这个问题的明确答案 # Get only

基本上,我有一个数组,比如说
@badvalues

我有另一个数组,比如说
@values

基本上,我想要这个:

对于
@badvalues

  • 查看它是否位于
    @values
  • 如果是,请将其删除
  • 最终,我应该得到一个数组
    @values
    ,它不包含数组
    @badvalues
    中的任何元素,或者一个新数组
    @goodvalues
    ,它包含
    @values
    中不是
    @badvalues
    元素的每个
    @values
    元素
我知道这听起来很简单,也许是因为我累了,但在四处搜索时,我似乎找不到这个问题的明确答案

# Get only bad values
my %values = map {$_=>1} @values;
my @new_badvalues = grep { !$values{$_} } @badvalues;

# Get only good values
my %badvalues = map {$_=>1} @badvalues;
my @goodvalues = grep { !$badvalues{$_} } @values;

# An alternative
@badvalues{@badvalues} = ();
foreach $item (@values) {
    push(@goodvalues, $item) unless exists $badvalues{$item};
}

有关更完整的参考资料,请参阅“Perl Cookbook”的“第4.7章:在一个数组中查找元素,而不是在另一个数组中查找元素”

如果您有一个现代Perl版本,比如说>=5.10.1,那么您也可以这样做:

my@final\u good=grep{!($\~~@badvalues)}@values

或者为了更清楚地说明:

my@final\u good=grep{not$\~~@badvalues}@values


这使用的是Perl 5.10中添加的smartmatch操作符。

中所示方法的速度稍微快一点,占用内存更少


非常感谢。Stackoverflow:从2010年开始同时引用weed和Perl!我希望我使用的Perl能够如此现代,我现在使用的是5.6.1:(谢谢你的提示,我会记住的。@Interwebs-我会为你感到难过,但是我们的一些东西仍然停留在5.005上。真丢脸!我怀疑世界上是否存在代码,除了一些病态的情况,在这些情况下,进行上述优化将明显有益。但是,它会降低可读性。这段代码正在使用哈希生成器我的第二个例子中的r,然后是第一个例子中的hash用法:)。当然,这仍然是一个有效的代码-这条评论是我为什么没有包括这个解决方案的借口;而不是对你的批评:)@szbalint:你可能会感到惊讶,但写这样的代码是有实际理由的。编写这种perl代码要比在XS模块中编写可读性差得多的C代码容易得多,从而获得38%的性能和38%的内存占用。这几乎是实际项目中可用和不可用速度的五分之二。如果您比较
my%badvalues=map{$\=>1}@badvalues和<代码>我的%BAD值@badvalues{@badvalues}=()可读性没有太大差别。@szbalint:取决于阅读器。如果您熟悉这个习惯用法,那么读取散列切片的空赋值要比读取映射容易
my %badvalues;
@badvalues{@badvalues} = ();
my @goodvalues = grep !exists $badvalues{$_}, @values;