Originally, I am working with a list with length = 2^16. However, to abstract this, I will set length = 5 in this example.
#subroutine to make undefined entries -> 0
sub zeros {
foreach(@_) {
if(!defined($_)) {
$_ = 0;
}
}
}
#print out and indicies and elements of list
sub checking {
print "List = \n";
my $counter = 0;
foreach (@_) {
print "index = $counter\n";
print "$_\n";
$counter += 1;
}
print "\n";
}
Method 1: If I access different indices to edit the element, I get the following when I print out the arrays. I dont want to see blank. I want them to be 0. I have already set up a subroutine "zeros" to make undefined entries become zero. But I dont know what went wrong in my code. I have also tried "$_ += 0" for each elements of the list. I still wasnt able to get zeros for empty entries.
#method 1
@abc = ();
$abc[1] = 3;
$abc[5] = 5;
&zeros(@abc);
&checking(@abc);
List =
index = 0
index = 1
3
index = 2
index = 3
index = 4
index = 5
5
And method 2: I can get zeros if I initialise the list like this. But as I said, I am working with very long list, I cannot definitely not initialise my list like this.
#method 2
@abc = (3,0,0,0,5);
&checking(@abc);
List =
index = 0
3
index = 1
0
index = 2
0
index = 3
0
index = 4
5
Your approach is correct, but there's an issue with your zeros()
function. You are calling it with @abc
as a parameter, which makes a copy of that list. You then change the copy. At the end of the sub, that copy is discarded. In your checking()
function, you are still using the original list.
You can fix it like this:
sub zeros {
my @list = @_;
@list = map { $_ // 0 } @list;
return @list;
}
@abc = zeros(@abc);
checking(@abc);
The trick is to return the altered list and reassign it to the original variable.
If you had used strict
and warnings
it would have told you about that:
Use of uninitialized value $_ in concatenation (.) or string at F:\scratch.pl line 28. List = index = 0
index = 1 3 index = 2
index = 3
index = 4
index = 5 5
Use of uninitialized value $_ in concatenation (.) or string at F:\scratch.pl line 28.
Use of uninitialized value $_ in concatenation (.) or string at F:\scratch.pl line 28.
Use of uninitialized value $_ in concatenation (.) or string at F:\scratch.pl line 28.
But since you are dealing with a very big array, I would advise to use an array reference instead because the copying will be expensive.
sub zeros {
$_ //= 0 for @{ $_[0] };
}
zeros(\@abc);
checking(@abc);
Can you initialise your list using
@abc = (0) x 2**16
which sets it to a list of 2**16 zeroes?
I tried using your zeroes method. It worked if I initialise the array like this:
@abc = (undef, 1, undef, undef, undef, 5)
So it looks like the subroutine doesn't replace array-entries that don't exist (as opposed to existing but having a value of undef
)
In which case you could try extending your zeros
subroutine to return the modified array and assign that back to the original array:
#subroutine to make undefined entries -> 0
sub zeros {
foreach(@_) {
if(!defined($_)) {
$_ = 0;
}
}
return @_;
}
@abc = ();
$abc[1] = 3;
$abc[5] = 5;
@abc = zeros(@abc);
# Check:
print "index = $_\n$abc[$_]\n" for 0..$#abc;
Alternatively, you could pass a reference to the original array:
#subroutine to make undefined entries -> 0
sub zeroref {
my ($array) = @_; # Expect a single argument: An array-reference
foreach(@$array) {
if(!defined($_)) {
$_ = 0;
}
}
}
@abc = ();
$abc[1] = 3;
$abc[5] = 5;
zeroref(\@abc); # Pass an array-reference instead
# Check:
print "index = $_\n$abc[$_]\n" for 0..$#abc;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With