cormanaz has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks. I have an array with n rows and m columns that I need to fill with zeros. I could do it the brutish way:
my @arr; for my $i (0..$n-1) { for my $j (0..$m-1) { $arr[$i][$j] = 0; } }
But isn't there a more perlified way to do it using map or X? Surprisingly, searches have not turned up much except a down-voted answer on stack overflow.

Replies are listed 'Best First'.
Re: Initialize a 2D array with zeros
by tybalt89 (Monsignor) on Jan 17, 2024 at 01:06 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11157035 use warnings; my $n = 4; my $m = 7; my @array = map [ (0) x $m ], 1 .. $n; use Data::Dump 'dd'; dd @array;

    Outputs:

    ( [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], )
Re: Initialize a 2D array with zeros
by etj (Priest) on Dec 10, 2024 at 14:54 UTC
    If you want a block of zeroes, then you may actually be looking for a PDL solution, in which case do:
    use PDL; $ndarray = zeroes($cols,$rows);
    If not, you can still do (albeit it's only somewhat efficient - most work is done in C and/or XS, not the interpreter):
    use PDL; $array_of_arrays = zeroes($cols,$rows)->unpdl;
Re: Initialize a 2D array with zeros
by harangzsolt33 (Deacon) on Jan 17, 2024 at 03:50 UTC
    Do you want a fast solution or a nice solution? I would create a string $str = ''; and do vec($str, 999999, 8) = 0; This is probably the fastest way to initialize a table (not to mention it's also the most memory-efficient solution as well.) This will initialize an "array" of characters 1000 x 1000. To access any value in this array, simply do this: vec($str, $Y*1000+$X, 8) where $X and $Y are the coordinates of your char array. If you need an array of integers, simply change the number 8 to 16 (or 32 for an array of 32-bit integers.)

    EDIT: To make it slightly more efficient, the "width" of your array should be a power of 2. So, instead of 1000 x 1000, you'd create 1024 x 1000, and then you would access any value in the array by doing this instead:    vec($str, $Y << 10 | $X, 8)    The only difference is that now we use the bitwise << shift operator and | OR operator in the calculation instead of multiplication and addition. When you use multiplication, Perl assumes that you're multiplying a 64-bit double, so it executes the FMUL function which is slow. But when you do bitwise operations, your calculation is classified as integer math which is way faster, especially when you have to do millions of calculations.