gpt4 book ai didi

带 $_ 的 Perl 多阶 grep

转载 作者:行者123 更新时间:2023-12-04 14:35:13 26 4
gpt4 key购买 nike

我正在努力学习 Perl 的 grep更好的。
我想 grep 散列的哪些键不在数组中

my %args = ( fake => 1);
my @defined_args = ('color', 'colors', 'data', 'figheight', 'figwidth', 'filename', 'flip', 'grid', 'labelsize', 'logscale', 'minor_gridlines');
my @bad_args = grep { not grep {$_} @defined_args} keys %args;
坏参数列表在 @bad_args 中最后一行显然是错误的。
我知道我可以用散列做同样的事情,但我希望能够用多阶 grep 来做到这一点,即 grep 上的 grep。
我怎样才能做到这一点,如下所示?
my @bad_args = grep { not grep {$_ eq $_} @defined_args} keys %args;
我很困惑,因为会有两个 $_ ,我无法对其进行相等测试。

最佳答案

首先是直接的答案——那个块 grep需要,您可以在其中放入任何代码。这就是块的重点,元素是否通过/不基于返回的最后一条语句的真实性。

my @bad_args = grep { 
my $key = $_;
@defined_args == grep { $key ne $_ } @defined_args
} keys %args;
这里我们测试一个键是否不等于数组元素,然后测试它是否不等于所有元素,由什么决定。另一种方法是测试它是否等于任何一个元素,
not grep { $key eq $_ } @defined_args;
这有点令人费解,需要使用否定。
但这些都是常见的事情,有图书馆。
直接改进上面的
use List::Util 1.33 qw(none);  # before 1.33 it was in List::MoreUtils

my @bad_args = grep {
my $key = $_;
none { $key eq $_ } @defined_args
} keys %args;
现在所需的“否定”被吸收在库的函数名称中,使其更容易查看。另外, none一旦它看到它失败就会停止 grep始终处理所有元素,因此这也更有效。
与基于散列的方法(复杂度为 O(NM-M2/2) 左右)相比,这些方法效率并不高,但这与小数组完全无关。问题中提到的哈希值用于与存在相关的问题是一个标准;参见例如 this post ,或下面讨论的所有库中使用的方法的来源( simplest example )。

最后,虽然问题是关于(双重)过滤的,但应该提到我们正在寻找列表的哪些元素不在另一个列表中;列表之间的“差异”。然后其他类型的库开始发挥作用。一些例子
使用 Set::Scalar
use Set::Scalar;
...

my $keys = Set::Scalar->new(keys %args);
my $good = Set::Scalar->new(@defined_args);

my $keys_not_in_good = $keys->difference($good);
say $keys_not_in_good;
另请注意 Set::Object在同一个营地。
然后还有专门用于数组比较的工具,比如 List::Compare
use List::Compare;
...

my $lc = List::Compare->new('-u', '-a', \@defined_args, [keys %args]);

my @only_in_second = $lc->get_complement();

say "@only_in_second";
选项 -u-a展示一些模块功能,以加快速度;它们不是必需的。该模块有很多,请参阅文档。
另一端是简单的 Array::Utils .
还有更多。参见例如 this page有很多想法。

关于带 $_ 的 Perl 多阶 grep,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69137487/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com