使用perl array_diff工具在2个数组之间的差异。

问题描述 投票:0回答:1

我试图在两个数组上运行array_diff。

sub array_diff(\@\@) {
    my %e = map { $_ => undef } @{$_[1]};
    return @{[
        ( grep { (exists $e{$_}) ? ( delete $e{$_} ) : ( 1 ) } @{ $_[0] } ),
        keys %e
    ] };
}

my $col = 'col';
my $stg = 'stg';
my @blocks = qw( block1 block2 block3 block4 block5 );
my %hash; @{$hash{$col}{$stg}} = qw( block1 block2 block3 );

my @diff = array_diff(@all_blocks, @{$hash{$col}{$stg}});
print ("diff : @diff\n");

当执行上面一行时,它给我以下错误。

Possible unintended interpolation of @diff in string at get_blocks.pl line 56.
Type of arg 2 to main::array_diff must be array (not reference constructor) at get_blocks.pl line 55, near "})"
syntax error at get_blocks.pl line 55, near "})"
Execution of get_blocks.pl aborted due to compilation errors.

然而当我尝试在没有数组的情况下运行同样的错误时,它却能正常工作。

my @a = qw( a b c d e);
my @b = qw( c d  );

sub array_diff(\@\@) {
    my %e = map { $_ => undef } @{$_[1]};
    return @{[
        ( grep { (exists $e{$_}) ? ( delete $e{$_} ) : ( 1 ) } @{ $_[0] } ),
        keys %e
    ] };
}
# symmetric difference
my @diff = array_diff(@a, @b);
print ("diff : @diff\n");

结果:我试图在两个数组上运行array_diff。

diff : a b e
arrays perl hash diff array-difference
1个回答
4
投票

我们可以参考 霹雳火 来找出错误和警告。

Possible unintended interpolation of @diff in string at get_blocks.pl line 56.

W模棱两可)你在双引号字符串中说了类似'@foo'这样的话,但当时范围内没有数组@foo。如果你想要一个字面的@foo,那么就把它写为 \@foo否则就会发现你丢失的数组是怎么回事。

你正在做的是 "@diff" 不过 @diff 未声明。

Type of arg 2 to main::array_diff must be array (not reference constructor) at get_blocks.pl line 55, near "})"

(F) 该函数要求该位置的参数必须是某种类型。数组必须是@NAME或@{EXPR}。. 哈希值必须是%NAME或%{EXPR}。. 不允许隐式注销--使用{EXPR}形式作为显式注销。参见 perlref。

就像它说的那样 \@ 原型必须取一个数组,而不是引用。

# Bad
array_diff([1,2,3], [4,5,6]);

# Good
array_diff(@{[1,2,3]}, @{[4,5,6]});

你的示例代码和你的错误不匹配。@diff 的声明,而你已经去掉了对 $hash{$col}{$stg}.


我建议不要使用原型。它们不像在其他语言中声明一个函数的参数一样,而是用来模拟内置函数的神奇行为。相反,它们是用来模拟内置函数的神奇行为的。

取而代之的是传递引用。

my @diff = array_diff(\@all_blocks, $hash{$col}{$stg});

真正的子程序签名 遗憾的是还在试验阶段。


没有必要 婴儿车司机 @{[]} 左右 grep. grep 已经返回了一个新的数组,没有必要再去克隆它。这样会使代码复杂化,浪费内存。

© www.soinside.com 2019 - 2024. All rights reserved.