我想比较2个数组并想要diff,common和intersect值,但是代码下面的代码不起作用。 没有错误消息所有我可以看到数组作为值,虽然我调用$ difference [0]所以我怀疑代码是否正确。
sub updatedevice() {
my $n = {};
my $Device_LINK = $server->object("ICF_PersistentDataSet",$devicelinks);
my $Temp_Device_LINK = $server->object("ICF_PersistentDataSet",$tempdevicelinks);
my @current_devicelist = @{ $Device_LINK->invoke("get") };
my @temp_devicelist = @{ $Temp_Device_LINK->invoke("get") };
my %temp_list;
my %current_list;
my $size = @current_devicelist;
for ($n=0; $n < $size; $n++) {
our $device=$current_devicelist[$n][0];
DEBUG( "DEBUG: - devicelinks values $device " ); --- > able to print this value of device "ABC-DCFE41->90"
my $size = @temp_devicelist;
for ($n=0; $n < $size; $n++) {
our $tempdevicelinks=$temp_devicelist[$n][0];
DEBUG( "DEBUG: - temp plc links values $tempdevicelinks " ); --- > able to print this value of device "GHJKL-poiu->78"
my %count = ();
foreach my $device (@current_devicelist, @temp_devicelist) {
$count{$device}++;
}
my @difference = grep { $count{$_} == 1 } keys %count;
my @intersect = grep { $count{$_} == 2 } keys %count;
my @union = keys %count;
DEBUG( "DEBUG: - difference links values $difference[0] " );
DEBUG( "DEBUG: - intersect links values $intersect[0] " );
DEBUG( "DEBUG: - union links values $union[0] " );
}
}
}
答案 0 :(得分:2)
问题是您正在分配数组引用(从invoke
返回到数组)。
你的“看'数组'作为一个值”的陈述是一个死的赠品,你正在操纵数组引用(而不是数组) - 打印时,它们变成这样的字符串:'ARRAY(0x349014)'
问题在于你正在获取一个数组引用(一个标量),并将它分配给一个数组 - 它会对你的值施加列表上下文,并将该标量转换为一个列表,其中唯一的元素就是标量。 因此,您只需将数组引用存储为数组的第一个也是唯一的元素,而不是存储像您预期的那样引用的值列表。
演示:
my @current_devicelist = (1,3); # Assign real arrays
my @temp_devicelist = (2,3);
my %count = ();
foreach my $device (@current_devicelist, @temp_devicelist) {
$count{$device}++;
}
my @difference = grep { $count{$_} == 1 } keys %count;
my @intersect = grep { $count{$_} == 2 } keys %count;
my @union = keys %count;
use Data::Dumper;
print Data::Dumper->Dump([\@difference, \@intersect, \@union]
,["difference","intersect","union"]);
打印:
$difference = [
'1',
'2'
];
$intersect = [
'3'
];
$union = [
'1',
'3',
'2'
];
现在,如果您通过将前两行更改为:
来模仿代码的作用my @current_devicelist = [1,3]; # Assign reference
# Works the same as if you said
# my @current_devicelist = ([1,3]);
# or
# my $current_devicelist[0] = [1,3];
my @temp_devicelist = [2,3];
...你得到:
$difference = [
'ARRAY(0x349014)',
'ARRAY(0x349114)'
];
$intersect = [];
$union = [
'ARRAY(0x349014)',
'ARRAY(0x349114)'
];
要解决您的问题,您可以执行以下四项操作之一:
使用@{}
取消引用
my @current_devicelist = @{ $Device->invoke("get") };
my @temp_devicelist = @{ $Temp_Device->invoke("get") };
更改invoke()
方法 - 如果可以 - 返回数组而不是数组引用:
# Old code:
# return $myArrRef;
# New Code:
return @$myArrRef;
更改invoke()
方法 - 如果可以 - 根据上下文返回数组或arrayref(使用wantarray
):
# Old code:
# return $myArrRef;
# New Code:
return wantarray : @$myArrRef : $myArrRef;
更改代码以使用数组引用
my $current_devicelist = $Device->invoke("get");
my $temp_devicelist = $Temp_Device->invoke("get");
my %count = ();
foreach my $device (@$current_devicelist, @$temp_devicelist) {
$count{$device}++;
}