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

I saw so many posts on multi-dimensional array sizes. In those they are trying to check one dimension size. But I need the max dimension available in my array.

my @array = []; $array[2][3] = 1; $array[345][10] = 2; $array[2][65535] = 10;
How to know the dimensions like this ????

Expected Output:

 Dimensions are : 345 x 65535

Replies are listed 'Best First'.
Re: Max dimensions of multi-dimensional array
by BrowserUk (Patriarch) on Jul 13, 2016 at 07:30 UTC

    use List::Util qw[ max ]; my @array = []; $array[2][3] = 1; $array[345][10] = 2; $array[2][65535] = 10; ;; print $#array, 'x', max( map $#{ $_ // [] }, @array );; 345 x 65535

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Can you Please explain the print statement line a little.

        print $#array, 'x', max( map $#{ $_ // [] }, @array );;
        1. $#array is the largest index of @array;
        2. $#{ $_ } is the largest index of the array referenced by $_
        3. map assigns each of the values in @array to $_ in turn.
        4. Many of them will be undefined, if so, // [] substitutes an empty array for that value.
        5. Thus, the map extracts the highest indexes of all the subarrays in @array and substitutes 0 for those that are empty or don't exist.
        6. max() finds and returns the largest of those.

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Max dimensions of multi-dimensional array
by AnomalousMonk (Archbishop) on Jul 13, 2016 at 10:54 UTC
    my @array = [];

    BTW, I don't know what you expected the quoted statement from the OPed code to do, but what it does is to initialize  @array with a single element: a reference to an empty anonymous array.

    c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dump qw(dd); ;; my @array = []; dd \@array; ;; $array[2][3] = 1; $array[3][4] = 2; $array[2][6] = 10; ;; dd \@array; " [[]] [ [], undef, [undef, undef, undef, 1, undef, undef, 10], [undef, undef, undef, undef, 2], ]


    Give a man a fish:  <%-{-{-{-<

      I understand that now. I have to use '()' to maintain AoA. If i need an reference I need '[]'. Thanks for the clarification.

Re: Max dimensions of multi-dimensional array
by Anonymous Monk on Jul 13, 2016 at 07:22 UTC
    print heMentions(\@array), "\n"; sub heMentions { my( $arrayref ) = @_; my $width = 0; my $height = @$arrayref; for my $ref ( @$arrayref ){ my $wee = @$ref; if( $wee > $width ){ $width = $wee; } } return "Dimensions are : $height x $width"; }
Re: Max dimensions of multi-dimensional array -- oneliner
by Discipulus (Canon) on Jul 13, 2016 at 08:43 UTC
    just for my amusement..
    perl -e "$array[345][10]=1;$array[2][65535]=1; print qq($#array x ),ma +p{scalar @$_ -1}(sort{scalar @$b<=>scalar @$a}@array)[0]" 345 x 65535

    Dunno why i needed to swap $a and $b ..

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Because you use the first element from your sorted list instead of the last.

      scalar isn't needed in the sort comparison because <=> puts the two array references into scalar context any way. For your code to be strictly correct (run without error under strictures) you need to deal with undefined array elements too. The cleaned up and strictly correct code looks like:

      use warnings; use strict; my @array; $array[345][10] = 1; $array[2][65535] = 1; print qq($#array x ), map {scalar @$_ - 1} (sort {@$a <=> @$b} map {$_ // []} @array)[-1 +];

      Prints:

      345 x 65535
      Premature optimization is the root of all job security
        Oh the hot summer air has obnubilated my mind.. thanks GrandFather for your fresh breeze!

        L*

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Max dimensions of multi-dimensional array
by BillKSmith (Monsignor) on Jul 13, 2016 at 13:04 UTC

    The reason you cannot find any documentation about the maximum size available for an array is that arrays expand as needed. They are limited only by memory available.

    Because each index starts at zero, when you store the elements you specified, the size of your array will expand to 346 x 65536 (if it is not at least that large already).

    The solutions you have received do not give the same result. One gives the maximum index that has been used for each dimension. The other gives the current sizes (which are each one greater).

    Bill
      ... arrays expand as needed. ... the size of your array will expand to 346 x 65536 ...

      That's a bit misleading. It implies the allocation of space for a | an orthogonal multi-dimensional array of 346 * 65,536 == 22,675,456 elements. Because Perl multi-dimensional arrays are "ragged", each array "dimension" (update: maybe "vector" would be a better term here) is only allocated the space it actually needs. I count the array specified in the OPed code like this:

      • @array array of 346 elements, mostly undefined;
      • $array[0] reference to an empty array;
      • $array[1] undefined, doesn't exist as an array;
      • $array[2] reference to an array of 65536 elements, only two of which are defined;
      • array elements  @array[3 .. 344] are undefined;
      • $array[345] reference to an array of 11 elements, only one of which is defined.

      By my count, I get a total of 346 + 65,536 + 11 == 65,893 elements, almost all of which are undefined; the array, as it stands, is very sparse.

      Update: Please see Manipulating Arrays of Arrays in Perl (perllol) and Perl Data Structures Cookbook (perldsc).


      Give a man a fish:  <%-{-{-{-<