Perl - 数组的过滤函数

onl*_*lyf 1 arrays perl filter

我正在尝试创建一个执行以下操作的子例程:

  1. 将两个数组作为输入(Filter,Base)
  2. 仅输出第一个中不存在的第二个数组的值

示例:

@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
}
Run Code Online (Sandbox Code Playgroud)

测试运行 :

@filter = ( 'Tom', 'John' ); 
@array = ( 'Tom', 'John', 'Mary' );
@array3 = filter_list(@filter,@array);
print @array3;
print "\n";
Run Code Online (Sandbox Code Playgroud)

结果:

JohnJohnMary
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗?谢谢.

ike*_*ami 5

您不能将数组传递给subs,只传递标量.所以,当你这样做

my @filtered = filter_list(@filter, @base);
Run Code Online (Sandbox Code Playgroud)

你真的在做

my @filtered = filter_list($filter[0], $filter[1], ..., $base[0], $base[1], ...);
Run Code Online (Sandbox Code Playgroud)

因此,当你这样做

my @names = shift;
Run Code Online (Sandbox Code Playgroud)

你真的在做

my @names = $filter[0];
Run Code Online (Sandbox Code Playgroud)

这显然是错的.

最简单的解决方案是将引用传递给数组.

my @filtered = filter_list(\@filter, \@base);
Run Code Online (Sandbox Code Playgroud)

哈希允许有效的实现(O(N + M)).

sub filter_list {
   my ($filter, $base) = @_;
   my %filter = map { $_ => 1 } @$filter;
   return grep { !$filter{$_} } @$base;
}
Run Code Online (Sandbox Code Playgroud)

或者,

my @filtered = filter_list(\@filter, @base);
Run Code Online (Sandbox Code Playgroud)

可以实现为

sub filter_list {
   my $filter = shift;
   my %filter = map { $_ => 1 } @$filter;
   return grep { !$filter{$_} } @_;
}
Run Code Online (Sandbox Code Playgroud)