Reputation: 86
I just want to assign the value of the AB array to the last position of the ABU array.
$ABU->[1][-1][1] = $AB->[1][$i][1];
And every time this assignation occurs, the AB array gets modified.
for ($i = 1; $i < $lenghtf; $i++) {
if ($ABU->[1][-1][1] < $AB->[1][$i][0]) {
push (@{$ABU->[1]}, $AB->[1][$i]);
} elsif ($ABU->[1][-1][1] < $AB->[1][$i][1]){
$ABU->[1][-1][1] = $AB->[1][$i][1];
}
}
If I do
print Dumper ($AB[1]);
before the loop and
print Dumper {ABU => $ABU, AB => $AB};
after the loop, I get this output:
![enter image description here][1]
After people's answers, I have realised that the problem may be when I assign the first value to ABU[1] before the loop:
push (@{$ABU->[1]}, $AB->[1][0]);
If I do print with dumper before the loop:
I've tried to change that firs asignation syntax:
push (@{$ABU->[1]}, @{$AB->[1][0]});
And then the Dumper looks better:
The problem now is that I don't know why when I run the for loop it complains in the first if line:
if ($ABU->[1][-1][1] < $AB->[1][$i][0]) {
with this STDERR:
Can't use string ("15") as an ARRAY ref while "strict refs"
Upvotes: 1
Views: 107
Reputation: 26131
The problem is this line
push (@{$ABU->[1]}, $AB->[1][$i]);
Here you clearly insert a reference to the array. It will be seen at result of print Dumper {ABU => $ABU, AB => $AB};
which is missing in your question. But it can be seen in the next image.
See this $VAR->{ABU}[1][0]
. After few cycles, you will end up with multiple references to the same array.
For your data format, you can do
push @{$ABU->[1]}, [@{$AB->[1][$i]}];
But using some cloning routine would be more robust (immune to the feature code changes which inevitably come with time).
use Storable qw(dclone);
push @{$ABU->[1]}, dclone($AB->[1][$i]);
BTW your code could be written
use Storable qw(dclone);
for my $ab_row (@{$AB->[1]}) {
my $last_abu_row = $ABU->[1][-1];
if ($last_abu_row->[1] < $ab_row->[0]) {
push @{$ABU->[1]}, dclone($ab_row);
} elsif ($last_abu_row->[1] < $ab_row->[1]) {
$last_abu_row->[1] = $ab_row->[1];
}
}
Edit:
The expression push @{$ABU->[1]}, [@{$AB->[1][$i]}];
:
$AB->[1][$i]
is array reference
@{$AB->[1][$i]}
is content of array refrenced by $AB->[1][$i]
[@{$AB->[1][$i]}]
is array reference to fresh new array with content of array referenced by $AB->[1][$i]
. It is shorthand of:
do {
my @array; # fresh new array
@array = @{$AB->[1][$i]}; # Here you copy content of array
\@array; # return reference to the new array
}
Then you push it to the array referenced by $ABU->[1]
. After this statement $ABU->[1][-1]
contains array reference to the new array with content copied from array referenced by $AB->[1][$i]
.
In contrast push @{$ABU->[1]}, $AB->[1][$i];
$AB->[1][$i]
is array reference
which you push into the array referenced by $ABU->[1]
. So you push array reference referencing the original array. In other words, after the statement $ABU->[1][-1] = $AB->[1][$i]
, the same array reference.
The third statement push @{$ABU->[1]}, @{$AB->[1][$i]};
will push content of array referenced by $AB->[1][$i]
. It means you don't add one new element to the array referenced by $ABU->[1]
but same amount of elements as @{$AB->[1][$i]}
contains. It breaks reference but doesn't do what you want. You could fix it this way:
push @{$ABU->[1]}, [];
push @{$ABU->[1][-1]}, @{$AB->[1][$i]};
but it is less elegant way of writing push @{$ABU->[1]}, [@{$AB->[1][$i]}];
.
Upvotes: 3
Reputation: 373
You are non showing so much code. Maybe both $ABU and $AB are references to same array.
Upvotes: 1