I want to compare 2 arrays and want diff , common and intersect values but below code is not working. No error message all I can see Array as an value although I am calling $difference[0] so I doubt if the code is correct.
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] " );
}
}
}
The problem is that you're assigning array reference (returned from invoke
to an array).
Your statement of "see 'array' as a value" is a dead giveaway that you're manipulating array references (instead of arrays) - when printed, they turn into strings like this: 'ARRAY(0x349014)'
The problem is that you're taking an array reference (a scalar), and assigning it to an array - which imposes list context on your value, and turns that scalar into a list with its only element being that scalar. Thus you simply store the array reference as the first and only element of the array - instead of storing the list of values that's being referenced like you intended.
To demonstrate:
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"]);
This prints:
$difference = [
'1',
'2'
];
$intersect = [
'3'
];
$union = [
'1',
'3',
'2'
];
Now, if you mimique what your code was doing instead by changing the first 2 lines to:
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];
... you get:
$difference = [
'ARRAY(0x349014)',
'ARRAY(0x349114)'
];
$intersect = [];
$union = [
'ARRAY(0x349014)',
'ARRAY(0x349114)'
];
To fix your problem, you can do one of 4 things:
Simply dereference your returned array references, using @{}
dereference:
my @current_devicelist = @{ $Device->invoke("get") };
my @temp_devicelist = @{ $Temp_Device->invoke("get") };
Change invoke()
method - if you can - to return an array instead of array reference:
# Old code:
# return $myArrRef;
# New Code:
return @$myArrRef;
Change invoke()
method - if you can - to return an array OR an arrayref based on context (using wantarray
):
# Old code:
# return $myArrRef;
# New Code:
return wantarray : @$myArrRef : $myArrRef;
Change your code to use array references
my $current_devicelist = $Device->invoke("get");
my $temp_devicelist = $Temp_Device->invoke("get");
my %count = ();
foreach my $device (@$current_devicelist, @$temp_devicelist) {
$count{$device}++;
}