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

Hi Monks,

I know that $#A returns the last index of an array @A. And scalar @A returns the number of items in an array @A. But if I have a multi-dimensional array of fields that looks something like this:

@A = ([0,1],[0,...,0],[1,...,1])

scalar @A returns the number of items in the first field: 2. OK. $#A returns the last index in the first field: 1. Also OK.

But how do I find out how many zeros are in the second field? Or ones in the third field? I don't really care if its the index of the last item or the actual number of items. Like any good programmer I tried Googling the heck out of this but have come up empty handed.

Replies are listed 'Best First'.
Re: Find number of items in a field multi-demensional array
by Marshall (Canon) on Apr 26, 2018 at 18:55 UTC
    This is a "ragged" 2 D array (I guess, the "dots" aren't proper syntax)

    AoA means that essentially X[0] is a reference to an array.

    #!/usr/bin/perl use strict; use warnings; my @X = ([0,1],[0,0,0],[1,1,1,1,1,1,1,1,1]); #This is a ragged 2 D array foreach my $row_ref (@X) { print "num of elements this row: ", scalar (@$row_ref), "\n"; } __END__ num of elements this row: 2 num of elements this row: 3 num of elements this row: 9
    Update: "ragged" means that each row has a different number of columns. That is completely fine. Often each row has exactly the same number of elements and that is called a "matrix", like 2 x 3 or 3x5, etc.

    A simple array is like: @array=(1,2,3). A 2-D matrix is made up of references to arrays like that. So, essentially the first dimension of the 2D array is an array of references to other arrays that contain the actual data.

    scalar @A returns the number of items in the first field. No...that would be the number of rows in the ragged 2D matrix.

Re: Find number of items in a field multi-demensional array
by stevieb (Canon) on Apr 26, 2018 at 18:45 UTC

    You need to iterate over the top-level array, and then work on each element individually. Here's an example:

    use warnings; use strict; my @aoa = ( [qw(1 1 1 1)], [qw(2 2 2)], 'a string', [qw(3 3 3 3 3 3 3)], {a => 1, b => 2}, ); my $index = 0; for (@aoa){ if (ref $_ eq 'ARRAY'){ my $element_count = scalar @$_; print "elem $index has $element_count elements\n"; } else { print "elem $index is not an array reference\n"; } $index++; }

    Output:

    elem 0 has 4 elements elem 1 has 3 elements elem 2 is not an array reference elem 3 has 7 elements elem 4 is not an array reference
Re^2: Find number of items in a field multi-demensional array
by huck (Prior) on Apr 26, 2018 at 19:08 UTC

    While the prior replies are very good general answers, if you wanted to directly find the size of just the second array in the AoA @A you could use  scalar(@{$a[1]}) where $a[1] is the reference to the second list and  @{$a[1]} deferences that to an array and  scalar(@{$a[1]}) takes the size of that.

    edit: opps i should have replied to the OP and not a reply, sorry

    2018-05-16 Athanasius reparented to OP

Re: Find number of items in a field multi-demensional array
by haj (Vicar) on Apr 26, 2018 at 18:56 UTC
    I assume that the "fields" are the lists in square brackets? If @A = ([0,1],[0,1,2,3,0],[1,2,3,4,1]) then scalar @A is 3 and $#A is 2. Both count the items in the top-level list, and not the number of items in the first field. To count items of a specific field you need to isolate that field, and then use something like scalar grep { BLOCK } @list for counting:
    my @A = ([0,1],[0,1,2,3,0],[1,2,3,4,1,1,1,11]); my $zeroes = scalar grep { $_ == 0 } @{$A[1]}; my $ones = scalar grep { $_ == 1 } @{$A[2]}; print "Scalar : ", scalar @A, "\n"; print "Last index: $#A\n"; print "Zeroes in second field: $zeroes\n"; print "Ones in third field: $ones\n";