I am building five arrays in perl like (null, null, 32, 54, null, 59). So I first put the values that I know at specific index and fill the others with null. I do this like this
my @p0_series, @p1_series;
$p0_series[2] = "test";
$p1_series[3] = "string";
$p2_series[2] = "hello";
$p3_series[2] = "hi";
for($a = 0; $a < 5; $a++) {
if(!defined $p0_series[$a]) {
$p0_series[$a] = null;
}
if(!defined $p1_series[$a]) {
$p1_series[$a] = null;
}
if(!defined $p3_series[$a]) {
$p3_series[$a] = null;
}
if(!defined $p4_series[$a]) {
$p4_series[$a] = null;
}
if(!defined $p5_series[$a]) {
$p5_series[$a] = null;
}
}
I am trying to reduce this code to simpler one but I am not able to use the variable name p0_series, p1_seires dynamically in a loop. I tried like
for($a=0: $a <5; $a++ ){
if(!defined $p$i_series[$a] ) {
# assign values;
}
}
Which is not working. I am new to perl any help is appreciated. Is it possible I can assign the null value to all the undef elements in the array in a simpler manner?
Perl doesn't have null
, but it has undef
– which incidentally is the default value for unassigned elements in arrays:
my @array = (undef, undef, 32, 54, undef, 59);
creates the same structure as:
my @array;
$array[2] = 32;
$array[3] = 54;
$array[5] = 59;
There is no need to assign the other fields to undef
yourself.
If you are trying to assign a default value to elements which are currently undef
, you could write something like this (but note the limitations below):
defined or $_ = "default" for @array;
On Perl 5.10 or later, you can use the //
defined-or operator:
$_ //= "default" for @array
To assign defaults for multiple arrays:
$_ //= "default" for @array, @other_array
If you want to set an array to a specific length, you can do $#array = $length - 1
, so this actually specifies the highest index. This removes entries from longer arrays. For shorter arrays, the newly created entries will all be undef
.
There is a small problem with this: Perl has two kinds of undef
:
Scalars can contain the value “undef” like my $foo = undef
.
This is the case if we initialize the whole array at once like my @array = (undef, undef, 32, 54, undef, 59)
.
Unassigned values in arrays or hashes share their undef
scalar, which is read-only.
This is the case when we initialize the array by assigning some indices only, like $array[4] = 2
.
Usually this is no problem, but in a for-loop, the $_
is an alias to the current scalar, which in our case can be readonly. Therefore we can't always do $_ //= "default" for @array
but must either:
Assign directly into the array element, which creates an assignable scalar in that slot:
$array[$_] //= "default" for 0 .. $#array;
For multiple arrays:
for my $ref (\\@array, \\@other_array) { $ref->[$_] //= "default" for 0 .. $#$ref; }
Don't assign to the element and create a copy of the array with defaults instead:
@array = map { $_ // "default" } @array;
For multiple arrays:
@$_ = map { $_ // "default" } @$_ for \\@array, \\@other_array;
While I perceive this as more elegant, there can be some problems with this as each array element is copied.
Agreed, but just incase in perl you can also create run-time variable name. As in your case
if(!defined $p$i_series[$a] )
if (!defined ${"p$i"."_series"}[$a] )
This should do the job and create the variable $p1_series[$a] , $p2_series[$a] and further on
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.