我正在尝试创建一个执行以下操作的子例程:
示例:
@a = ( 1, 2, 3, 4, 5 );
@b = ( 1, 2, 3, 4, 5, 6, 7);
Expected output : @c = ( 6, 7 );
Called as : filter_list(@filter, @base)
###############################################
sub filter_list {
my @names = shift;
my @arrayout;
foreach my $element (@_)
{
if (!($element ~~ @names )){
push @arrayout, $element;
}
}
return @arrayout
}
测试运行:
@filter = ( 'Tom', 'John' );
@array = ( 'Tom', 'John', 'Mary' );
@array3 = filter_list(@filter,@array);
print @array3;
print "\n";
结果:
JohnJohnMary
有人可以帮忙吗?谢谢。
答案 0 :(得分:5)
您不能将数组传递给subs,只传递标量。所以当你这样做时
my @filtered = filter_list(@filter, @base);
你真的在做什么
my @filtered = filter_list($filter[0], $filter[1], ..., $base[0], $base[1], ...);
因此,当你这样做时
my @names = shift;
你真的在做什么
my @names = $filter[0];
这显然是错误的。
最简单的解决方案是将引用传递给数组。
my @filtered = filter_list(\@filter, \@base);
哈希允许有效实现(O(N + M))。
sub filter_list {
my ($filter, $base) = @_;
my %filter = map { $_ => 1 } @$filter;
return grep { !$filter{$_} } @$base;
}
可替换地,
my @filtered = filter_list(\@filter, @base);
可以实现为
sub filter_list {
my $filter = shift;
my %filter = map { $_ => 1 } @$filter;
return grep { !$filter{$_} } @_;
}
答案 1 :(得分:1)
你要找的是两套的差异。这个,以及联合,交集和其他一些是set operations。而不是自己编写,有很多modules for dealing with sets。
Set::Object非常快速且功能强大。我会避免使用操作员界面(即$ set1 - $ set2),因为它会使代码混乱。而是使用显式方法调用。
use strict;
use warnings;
use v5.10;
use Set::Object qw(set);
my $set1 = set(1, 2, 3, 4, 5);
my $set2 = set(1, 2, 3, 4, 5, 6, 7);
say join ", ", $set2->difference($set1)->members;
请注意,集合是无序的,不能包含重复项。这可能是也可能不是你想要的。
答案 2 :(得分:1)
这使用List::Compare,这是一个包含大量例程的模块,用于比较列表。
您需要get_complement
use warnings;
use strict;
use List::Compare;
my @arr1 = ( 1, 2, 3, 4, 5 );
my @arr2 = ( 1, 2, 3, 4, 5, 6, 7);
my $lc = List::Compare->new(\@arr1, \@arr2);
my @only_in_second = $lc->get_complement;
print "@only_in_second\n";
该模块有很多选择。
如果您不需要对结果进行排序,请将-u
传递给构造函数以加快操作速度。
还有通过-a
获得的" 加速模式"。为了在相同阵列之间进行有效的重复比较,许多事物在构造时被预先计算。使用此标志被抑制,这加速了单个比较。请参阅List::Compare Modes。
这两个选项可以合并,List::Compare->new('-u', '-a', \@a1, \@a2)
。
支持三个或更多列表上的操作。
还有功能界面,作为单独的List::Compare::Functional模块。