【问题标题】:items in array A that are not in array B [duplicate]数组A中不在数组B中的项目[重复]
【发布时间】:2019-01-27 04:20:19
【问题描述】:

有什么方法可以快速确定数组 A 中不存在于数组 B 中的项?

到目前为止我有以下,但是可以一行完成吗?

for $aname (@anames)
{
   if (not grep { $_ eq $aname } @hrefs)
   {
        push @anamesremove, $aname;
   }
}

【问题讨论】:

标签: arrays perl


【解决方案1】:

如果你知道哪个数组包含另一个

my @small  = 10..12;
my @large  = 10..15;

my %ref = map { $_ => 1 } @small;

my @diff = grep { not exists $ref{$_} } @large;

不完全是一条线,但效率很高。

如果不知道哪个包含另一个,则必须双向进行。

还有各种用于数组/列表操作的模块可以提供帮助。

一方面,来自List::Compareget_complement 正是需要的。


使用List::Util,您可以在一个语句中完成所有操作

use List::Util qw(none);

my @diff = grep { my $e = $_; none { $e eq $_ } @small } @large; 

但这有 O(NM-M2/2) 复杂度,其中 N(大)和 M em>(小)是数组大小。

【讨论】:

    【解决方案2】:

    不是单行,但在大型阵列上这可能比你的更快:

    #!/usr/bin/perl
    use warnings;
    use 5.012;
    
    sub difference {
        my ($first, $second) = @_;
        my %except;
        @except{ @$second } = 1;
        return [ grep { not exists $except{$_} } @$first ];
    }
    
    my @anames = ("one", "two", "three", "four", "five");
    my @hrefs = ("two", "four", "six");
    
    my $d = difference \@anames, \@hrefs;
    say "@$d";
    

    【讨论】:

    • @except{ @$second } = 1; 具有误导性。不如改用@except{ @$second } = ();
    • @ikegami 您是否认为它具有误导性,因为它可能被误解为计数而不是真实值?
    • 它看起来好像值被设置为1,但实际上并非如此。
    • 不。我认为我的方式在您只想在哈希中一次创建一堆键而不关心值是什么的情况下看起来更好(当然,除了其中一个将是undef)。使用空列表对我来说看起来很有趣。意见显然不同。
    • 如果你不关心值是什么,你肯定会很麻烦地假装它们是1。分配一个空列表是您实际上正在做的事情(“第一个”除外),您应该让您的代码看起来像它正在做的事情。 至少,使用假值而不是真值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2021-11-20
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多