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

Dear perl monks, I have used the essence of the code below for a while and first programmed it without thinking much about it. Now I am working through some structured perl tutorial and cannot find anything similar. Can anyone explain the notation $bin[$variable][$othervariable]? Thanks in advance, Annemarie
#! /usr/bin/perl $template="A2x2A3"; for $mag (50..90){ $abumax[$mag]=1; for $abu (1..100){ $bin[$mag][$abu]=0; } } while (<>){ ($mag,$abu)=unpack($template,$_); $bin[$mag][$abu]++; $abumax[$mag]=$abu if ($abu >$abumax[$mag]); } for $mag (50..90){ for $abu (1..$abumax[$mag]){ if ($bin[$mag][$abu] !=0){ printf"%2s %3s %3s\n", $mag, $abu, $bin[$mag][$abu]; } } }
A sample testfile looks like this:
50 1 50 2 53 5 54 2 50 2 53 5 54 2 50 2 53 5 54 2 64 5
The output looks like this:
50 1 1 50 2 3 53 5 3 54 2 3 64 5 1

Replies are listed 'Best First'.
Re: Counting frequency of occurrence - what am I doing?
by ikegami (Patriarch) on Mar 08, 2005 at 20:25 UTC

    Your arrays are rather sparse. You might want to use hashes instead. It would also rid you of the need of the (possibly arbitrary) limits of 50..90 and 1..100. It wouldn't hurt to use strict and warnings, either.

    #!/usr/bin/perl use strict; use warnings; my %bin; my $mag; my $abu; while (<>) { ($mag, $abu) = split(/\s+/, $_); $bin{$mag}{$abu}++; } foreach $mag (sort { $a <=> $b } keys %bin) { foreach $abu (sort { $a <=> $b } keys %{$bin{$mag}}) { printf("%2s %3s %3s\n", $mag, $abu, $bin{$mag}{$abu}); } }
Re: Counting frequency of occurrence - what am I doing?
by RazorbladeBidet (Friar) on Mar 08, 2005 at 20:11 UTC
    You want to know what $a[$var1][$var2] means?

    It's a two-dimensional array (or rather an array of array references) - Try starting here at perlreftut
    --------------
    It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
      I can only see actual numbers in the square brackets. So if I use an example from my value range, I could have something like  $a[50][3]. What about the arrays 0-49?
        As ikegami said (and I haven't really dug into the code) your arrays are sparse. Meaning those values are undefined.
        --------------
        It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
Re: Counting frequency of occurrence - what am I doing?
by trammell (Priest) on Mar 08, 2005 at 20:12 UTC
    That syntax is explained in perllol, among others.
Re: Counting frequency of occurrence - what am I doing?
by Joost (Canon) on Mar 08, 2005 at 20:13 UTC
Re: Counting frequency of occurrence - what am I doing?
by legato (Monk) on Mar 08, 2005 at 21:53 UTC

    As others point out quite well, $foo[$bar][$baz] is a List of Lists (array of arrays), which is basically the same thing as a multi-dimensional array in other languages.

    An additional point is that you aren't seeing hundreds of lines of output because many of the values in your data structure are undef, and undefined values are not printed. If you use warnings; the print statements acting on undefined values will notify you with "Use of undefined value in print or join".

    To see what the data structure looks like, use the module Data::Dumper::Simple and use

    print Dumper(@bin);
    to examine the structure of @bin. This will produce rather verbose output, so you may wish to redirect it to a file. Since the output is a Perl data structure, viewing it as a Perl file in a syntax-highlighting editor is most helpful.

    Instead of using an array, you may wish to use an "associative array", or hash, which uses strings rather than sequential numbers as keys. Of course, all numbers can be expressed as strings trivially, so little would need to change in your code. Hashes are only minutely slower than arrays (you won't notice unless you're processing huge amounts of data) -- but the reduction in memory you will experience in not having to have a 100-element array to store 4 results will likely make up for this anyhow.

    Anima Legato
    .oO all things connect through the motion of the mind

Re: Counting frequency of occurrence - what am I doing?
by Zaxo (Archbishop) on Mar 08, 2005 at 20:14 UTC

    That means @bin is a two dimensional perl array. It is technically a one-dimensional array of array references.

    You can simplify your data decoding with split

    while (<>) { my ($mag,$abu) = split; # . . . }
    There is nothing wrong with unpack there, but it is more fragile if the data format is chancy.

    After Compline,
    Zaxo