当我尝试以下操作时
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
print Dumper [grep {not @bl} @a];
我得到了一个空数组。我本来期望@a
减去@bl
后,输出结果为yellow purple pink
。
这里出了什么问题?
当我尝试以下操作时
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
print Dumper [grep {not @bl} @a];
我得到了一个空数组。我本来期望@a
减去@bl
后,输出结果为yellow purple pink
。
这里出了什么问题?
@bl
转换为哈希表以执行集合差异操作:my %in_bl = map {$_ => 1} @bl;
my @diff = grep {not $in_bl{$_}} @a;
my @diff = grep{ not $_ ~~ @bl } @a;
这将返回在数组 @a 中但不在数组 @bl 中的元素集合 @diff。 - Brad Gilbert$ _
与@bl
中的每个元素匹配。此答案只需迭代一次@bl
即可创建哈希表,因此性能差异显着。
http://perldoc.perl.org/perlop.html#Smartmatch-Operator - Floegipoky@b1
评估为 true(它是一个具有非零元素数量的数组),因此您 grep 构造中的布尔测试 (not @b1
) 将始终返回 false。grep 过滤一个数组,仅返回布尔测试返回 true 的元素。$_
是否在 @bl
中。一种方法是使用 @bl
作为键生成临时哈希表,然后在您的 grep 语句中检查是否存在于哈希表键中的 $_
。#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
# create a hash
my %h;
# nifty trick - use a hash slice to populate the
# hash. The values are irrelevant so we'll use @bl
# for those too
@h{@bl} = @bl;
print Dumper [grep {!exists $h{$_}} @a];
%h
的值有些过度了。如果使用 exists
,用 @h{@bl}=()
填充将会很好,并且可能更快。 - Stefan Majewsky#!/usr/bin/env perl
use warnings;
use 5.012;
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
my @s = grep{ not $_ ~~ @bl } @a;
say "@s"; # yellow purple pink
O(n^2)
的性能问题吗?因为智能匹配运算符会针对@a
中的每个元素匹配@bl
中的每个元素。 - Floegipokynot
可能不是您想要的结果。@bl
是一个空数组,则 not @bl
总是为 1
,如果 @bl
不为空,则为 undef
。它并不以任何方式表示“不在 @bl
中的元素”。使用perl5i的另一种选项:
use perl5i::2;
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
my @diff = @a->diff(\@bl);
say @diff->mo->perl;
另一种方法是使用Acme::Tools CPAN 模块中的 minus
函数:
use strict;
use warnings;
use Data::Dumper;
use Acme::Tools qw(minus);
my @bl = qw(red green blue);
my @a = qw(green yellow purple blue pink);
my @diff = minus(\@a, \@bl);
print Dumper(\@diff);
__END__
$VAR1 = [
'yellow',
'purple',
'pink'
];
另一种方法是使用:
List::Compare CPAN module
use List::Compare ;
...
my $compare_obj
= List::Compare->new(\@a , \@b1) ;
@diff = $compare_obj->get_Lonly() ;
...