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

Maxi Monks,

My apologies for "yet another multidimensional array question", but I'm getting tangled up....

I want to build a 3-d array (list) like this. I'm extracting variables out of a large csv file and grouping them by var_0. I want to end up with:
var_0 = a var_1 var_2 var_3
  var_1 var_2 var_3
  var_1 var_2 var_3

 

var_0 = b var_1 var_2 var_3
  var_1 var_2 var_3
  var_1 var_2 var_3

 

var_0 = c var_1 var_2 var_3
  var_1 var_2 var_3
  var_1 var_2 var_3
So I tried (among other things) coded for clarity
open(FILE, $theFile) or die("cannot open file : $!"); while (<FILE>) { $line = <FILE>; @line_parts = split (/\|/, $line); $var_0 = $line_parts[1]; $var_1 = $line_parts[7]; $var_2 = $line_parts[8]; $var_3 = $line_parts[9]; @tmp = ($var_1, $var_2, $var_3); push @{$theTable[$var_0]}, [ @tmp ]; } close(FILE);
But this - and my many variations - isn't working. Could someone point me in the right direction?

Replies are listed 'Best First'.
Re: Building three-dimensional array using push
by ikegami (Patriarch) on Dec 02, 2004 at 17:07 UTC

    Is $var_0 something like 'a', 'b' or 'c' as shown in the example, or is it numerical. If it's not numerical, $theTable[$var_0] won't work too well, but $theTable{$var_0} would work great. In other words, an HoAoA might be what you want, rather than an AoAoA.

    You forgot to chomp, so one of your parts has a trailing \n.

    my %theTable; while (<DATA>) { chomp; my @line_parts = split /\|/; $var_0 = $line_parts[1]; push(@{$theTable{$var_0}}, [ @line_parts[7, 8, 9] ]); } require Data::Dumper; print(Data::Dumper::Dumper(\%theTable), $/); __DATA__ 0|a|2|3|4|5|6|var_1|var_2|var_3 0|a|2|3|4|5|6|var_1|var_2|var_3 0|a|2|3|4|5|6|var_1|var_2|var_3 0|b|2|3|4|5|6|var_1|var_2|var_3 0|b|2|3|4|5|6|var_1|var_2|var_3 0|b|2|3|4|5|6|var_1|var_2|var_3 0|c|2|3|4|5|6|var_1|var_2|var_3 0|c|2|3|4|5|6|var_1|var_2|var_3 0|c|2|3|4|5|6|var_1|var_2|var_3
Re: Building three-dimensional array using push
by duff (Parson) on Dec 02, 2004 at 17:03 UTC

    It looks like what you really want is a hash indexed on what you're calling $var_0. Here's some code that'll do what I think you need.

    open(FILE, $theFile) or die("cannot open file : $!"); while ($line = <FILE>) { my($key,@parts) = (split (/\|/, $line))[1,7,8,9]; push @{$theTable{$key}}, [ @parts ]; } close(FILE);
      Since @parts is a tightly scoped my variable, [ @parts ] can be replaced with \@parts.
Re: Building three-dimensional array using push
by zejames (Hermit) on Dec 02, 2004 at 16:51 UTC
    while (<FILE>) { $line = <FILE>; ... } close(FILE);

    The <FILE> reads one line of the file each time. So with that code, $line is set with the data of only one line where two are read...

    You should use

    :
    my $line while ($line = <FILE>) { ... } close(FILE);

    HTH


    --
    zejames
Re: Building three-dimensional array using push
by punch_card_don (Curate) on Dec 02, 2004 at 17:33 UTC
    push @{$theTable{$key}},  [ @parts ]; Ya, that's exactly what I needed. Thanks.

    And also for the while ($line = <FILE>) Silly mistake...