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

I'm not sure how to ask my question, because I myself am confused as to how to do it. But I'll give my best shot.

I suppose what I am looking for is a multidemensional array, here's what I've got cooking....

I have an array, which references different "categories" if you will. For example, I have three categories...
$cat[0] = "birds"; $cat[1] = "turds"; $cat[2] = "flirds";
Each of these categories have individual listings, which are stored in a file $cat[$i].dat... there may be multipule lines in this file, for each individual listing.

I want to create one array, or multidementional array which holds all listings from all categories. How can I achieve that?

Thanks monks.

Replies are listed 'Best First'.
Re: confusing question, involving multidemensional arrays
by dragonchild (Archbishop) on Aug 09, 2001 at 19:43 UTC
    It sounds like what you want is a hash of arrays. You'd set it up something like:
    my $cat = { birds => [], turds => [], flirds => [], };
    Then, whenever you want to push a value onto one of those subarrays, like you just read a listing? Then do something like push @{$cat->{'birds'}}, $line;.

    If you have any further questions, please don't hesitate to ask. :)

    ------
    /me wants to be the brightest bulb in the chandelier!

    Vote paco for President!

      Paco's solution is probably what you want. man perlreftut or see Understand References Today for more info on the subject.

      But there's always the good old-fashioned Perl 4 approach:

      use strict; my %cat; $cat{'bird',0} = 'bluejay'; $cat{'bird',1}= 'oriole'; $cat{'mammal',0} = 'cat'; $cat{'mammal',1} = 'dog'; for (sort keys %cat) { my ($class, $num) = split $;; print "cat[$class][$num] = $cat{$_}\n"; }

      For sparse arrays whose use will be dominated by looking up things by known indices rather than processing rows or columns in a loop, I sometimes still use this. Note that it's inappropriate if your keys might contain binary data, because they can't contain the value of $;, by default \034.

Re: confusing question, involving multidemensional arrays
by davorg (Chancellor) on Aug 09, 2001 at 19:59 UTC

    At a basic level you can doe something like this:

    my @categories = qw(birds turds flirds); my %data; foreach (@categories) { local *DATA; open DATA, "$_.dat" or die "Can't open $_.dat: $!\n"; $data{$_} = [ <DATA> ]; }

    At this point you have a hash with three key/value pairs. The keys are the category names and the values are references to arrays which contain the data from the associated files.

    You may well want to do something more structured with the data in the files, but until we know what that is it's difficult to know what.

    The are more details on this in the perldoc perldsc manual page.

    --
    <http://www.dave.org.uk>

    Perl Training in the UK <http://www.iterative-software.com>

(bbfu) (multi-dim. array from files) Re: confusing question, involving multidemensional arrays
by bbfu (Curate) on Aug 09, 2001 at 19:51 UTC

    To make a multi-dimensional array, you just make an array, who's elements are references to anonymous arrays.

    $anon_array_ref = ['one', 'two', 'three']; @md_array = ( ['one', 'two', 'three'], ['four', 'five', 'six' ], # ...etc... ); print "Yep.\n" if($md_array[0][1] eq 'two'); my @data; for my $file (map "$_.dat", @cat) { open(my $fh, "< $file") or die "can't open $file: $!\n"; push @data, [<$fh>]; close $fh or die "can't close $file: $!\n"; } print $data[0][0];

    You might be better off using a hash, keyed by the categories, for the "outter" "array". Same principle applies: make each value a reference to an anonymous array.

    Update: Fixed bug, and make code more idiomatic. Use dragonchild's hash.

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

Re: confusing question, involving multidemensional arrays
by jlk (Hermit) on Aug 09, 2001 at 20:59 UTC

    I don't have it in front of me at the moment, but chapter 1 of the 3rd edition of the Camel book has an example of a multidimensional array that may help you with your problem.


    #jlk
    Learning Unix sometimes involves Pain, PaIn, PAIN!!
Re: confusing question, involving multidemensional arrays
by Anonymous Monk on Aug 09, 2001 at 21:54 UTC
    How do I find out how many references I have in one of my arrays?
    Like.. $#array = how many references are in that array... i want to do something like $#array1, but that doesn't work.
Re: confusing question, involving multidemensional arrays
by marvell (Pilgrim) on Aug 09, 2001 at 19:55 UTC

    Care to drop in an example dat file?

    One with complex entries would be splendid.

    --
    Brother Marvell

Re: confusing question, involving multidemensional arrays
by Anonymous Monk on Aug 09, 2001 at 20:42 UTC
    for ($i=0; $i<=$#list; $i++){ for ($j=0; $j<=$#list[$i]; $j++){ undef($name, $url, $cat, $desc); ($name, $url, $cat, $desc) = split (/\|/$list[$i][$j]); } }
    I've got my multidementional arrays setup now, but there is something wrong with this peice of code, and I can't find it.
Re: confusing question, involving multidemensional arrays
by Rhandom (Curate) on Aug 09, 2001 at 20:57 UTC
    In order to preserve your order you may want to do something like this:

    $cat[0] = ["birds", ["Sub array listing 0.1.0", "Sub array listing 0.1.1", ]]; $cat[1] = ["turds", ["Sub array listing 1.1.0", "Sub array listing 1.1.1", ]]; foreach my $elem ( @cat ){ my $name = $elem->[0]; print "My name is \"$name\"\n"; foreach my $sub_elem ( @{ $elem->[1] } ){ print "My Property is: $sub_elem\n"; } }


    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: confusing question, involving multidemensional arrays
by Anonymous Monk on Aug 09, 2001 at 21:55 UTC
    How do I find out how many references I have in one of my arrays?
    Like.. $#array = how many references are in that array... i want to do something like $#array[1], but that doesn't work.

      $#array gives you the highest-numbered index of @array, which is 1 less than the number of elements, because it counts from 0. Evaluating @array in a scalar context gives you the number of elements, an evaluation you can force with scalar @array.

      It works great with arrayrefs too... scalar @$arrayref gives you the number of elements in the array to which $arrayref refers; scalar @{$arrayref->[$i]} gives you the number of elements in the array ref that's the ith element in $arrayref.

Re: confusing question, involving multidemensional arrays
by princepawn (Parson) on Aug 09, 2001 at 19:57 UTC
    Some useful modules to deal with building, inspecting, and manipulating nested arrays are:
  • Data::DRef
  • Data::Dumper
  • Data::Denter

    And the best book I've found for learning how to deal with nested perl structures is "Advanced Perl Programming" by Sriram Srinivasan, which you can probably get for cheap as Perl 5 is on it's way out the door.