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

Hello monks!
I have recently came across arrays of arrays and I'm currently using them in a program of mine.
What I wanted to ask is there a quick way to count:
(i) the number of rows, and,
(ii) the number of columns
in a multidimensional array?
E.g.:
@AoA=( [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] );

Replies are listed 'Best First'.
Re: work with Array of Arrays
by toolic (Bishop) on Apr 18, 2010 at 01:13 UTC
    To count the rows, use scalar In general, if you need to count the number of columns in each row (since they need not be the same), you could use a for loop:
    use strict; use warnings; my @AoA=( [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ); print 'Number of rows = ', scalar @AoA, "\n"; for my $aref (@AoA) { print 'Number of cols = ', scalar @{$aref}, "\n"; } __END__ Number of rows = 3 Number of cols = 4 Number of cols = 4 Number of cols = 4

    See also:

Re: work with Array of Arrays
by jethro (Monsignor) on Apr 18, 2010 at 01:11 UTC
    $rows= @AoA; # more explicit: $rows= scalar @AoA; #only if all rows are the same size: $columns= @{$AoA[0]}; # == no. of columns in row 0
Re: work with Array of Arrays
by tilly (Archbishop) on Apr 18, 2010 at 03:31 UTC
Re: work with Array of Arrays
by biohisham (Priest) on Apr 18, 2010 at 04:41 UTC
    It is relatively easier to print the number of rows and columns for a list of lists if all columns for each row are of the same count, if that is not the case then it is possible with a little bit more lines to count the number of columns for individual rows, I would advice you to read References quick reference and also these ones here perlcheat, perlref and perlreftut for related tutorials and quick cheats on references...
    #!/usr/local/bin/perl use strict; use warnings; my @AoA=( [0, 1, 0, 0], [0, 0, 1, 0,0,0,0,0], [0, 0, 0, 1,0,1] ); # my $row = scalar @AoA; ##Prints the number of rows for the array for(my $i = 0; $i<=$#AoA;$i++){ my $count =0; foreach my $column (@{$AoA[$i]}){ $count ++; } print "Row# ", $i+1, " has $count columns\n"; }
    Update: On the behest of almut's reply, the above code is just a prove of concept to ways to generally iterate over lists of lists, I wrote it in a rush while thinking of an approach similar to almut's, my code above unnecessarily loops over array elements just to do an incrementation... Here's a more efficient approach
    for(my $i = 0; $i<=$#AoA;$i++){ my $count = @{$AoA[$i]}; print "Row #: ", $i+1, " has $count columns\n"; }


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
      my $count =0; foreach my $column (@{$AoA[$i]}){ $count ++; }

      When all you do in the loop is increment, you might as well just write

      my $count = @{$AoA[$i]};

      which, btw, is approximately N times faster, with N being the size of the array:

      use Benchmark 'cmpthese'; my @AoA; $AoA[42] = [ (1) x 1000 ]; cmpthese(-1, { counted => sub { my $count =0; foreach my $column (@{$AoA[42]}){ $count ++; } }, direct => sub { my $count = @{$AoA[42]}; }, } ); __END__ Rate counted direct counted 11821/s -- -100% direct 9267717/s 78297% --
Re: work with Array of Arrays
by shawnhcorey (Friar) on Apr 18, 2010 at 12:23 UTC

    Consider using Math::Matrix, especially if you're going to be doing more than just scanning the contents.

Re: work with Array of Arrays
by locked_user sundialsvc4 (Abbot) on Apr 20, 2010 at 02:37 UTC

    One thing that you need to bear in mind is: there is no such thing as "a multi-dimensional array per se in Perl."

    Instead, you have something far more powerful:   a list of references to other lists. (Hence, the various lists do not have to be of the same length.)

    The “breakthrough” is this:   that “a reference to (anything)” is always “a single thing,” no matter what it refers to at any particular moment.

Re: work with Array of Arrays
by chopper (Novice) on Apr 18, 2010 at 02:56 UTC
    use $#; <code>my @AOA=( 0,1,0,0, 0,0,1,0, 0,0,0,1 ); print $#AOA+1,"\n"; my @BOB=@{@AOA[0]}; print $#BOB+1,"\n";