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

Hello Monks,
I need a hash that points to an of Array of Arrays data struct. The data struct looks ok but the hash data itself is wrong. I am loading the first value in the record set in the other three positions.

How do I evaluate the existence data in this hash that contains an array of array?

Is there a more efficient way to load this data struct?

Recordset looks like the following:
334 Capped 28 5034366 16777215 + NULL NULL NULL 373 Capped 28 5034366 16777215 + NULL NULL NULL

This shows the current data struct. Notice that the data is the same in the arrays. This output is from Data::Dumper.
$VAR147 = '5034510'; $VAR148 = &#091 &#091 '308', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '308', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '308', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '308', 'Capped ', 210, 16777215, undef, undef &#093 ]

It should look like this:
$VAR147 = '5034510'; $VAR148 = &#091 &#091 '308', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '334', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '373', 'Capped ', 210, 16777215, undef, undef &#093, &#091 '291', 'Capped ', 210, 16777215, undef, undef &#093 ]


This is the code that loads the hash and array of arrays data struct. Something is wrong it loads only the first value in the recordset.

sub insert_carrier_values { my $array_ref = shift; my $hash_ref = shift; for my $aref (@$array_ref) { #element 3 in the Hash Key if ( $aref->[3] > 0 ) { #Load the Array of Array with all the records from the query with the +same element #3 if the Array does #not have something alreay there in postion 0 $hash_ref->{ $aref->[3] }[0] = [ $aref->[0], $aref->[1], $aref->[2], $aref->[4], $aref->[5], $aref->[6] ] unless defined( $rank{ $aref->[3] }->[0][0] ); # Same as above but now load postion # 1 if postion 0 if full $hash_ref->{ $aref->[3] }[1] = [ $aref->[0], $aref->[1], $aref->[2], $aref->[4], $aref->[5], $aref->[6] ] unless defined( $rank{ $aref->[3] }->[1][0] ); # Same as above but now load postion # 2 if postion 1 if full $hash_ref->{ $aref->[3] }[2] = [ $aref->[0], $aref->[1], $aref->[2], $aref->[4], $aref->[5], $aref->[6] ] unless defined( $rank{ $aref->[3] }->[2][0] ); # Same as above but now load postion # 3 if postion 2 if full $hash_ref->{ $aref->[3] }[3] = [ $aref->[0], $aref->[1], $aref->[2], $aref->[4], $aref->[5], $aref->[6] ] unless defined( $rank{ $aref->[3] }->[3][0] ); } } } # end sub insert_carrier_values

Replies are listed 'Best First'.
Re: Loading of Complex Data Structures
by bobf (Monsignor) on Aug 25, 2004 at 21:31 UTC

    I think I figured out what you're trying to do here. If I'm off a bit, try to use this as a base to build from. You might want to take a look at perlref, perlreftut, and perldsc to learn more about references and complex data structures.

    The example below should get you started. Since it appears you want to use a subroutine to add the array to the hash, I've coded it that way.

    HTH
    use strict; use warnings; use Data::Dumper; my %hash; my @array1 = qw( one two three ); my @array2 = qw( four five six ); my @array3 = qw( seven eight nine ); add_arrayref_to_hashref( \@array1, \%hash, 'key1' ); print "\nafter adding array1 using key1:\n", Dumper( \%hash ); add_arrayref_to_hashref( \@array2, \%hash, 'key1' ); print "\nafter adding array2 using key1:\n", Dumper( \%hash ); # getting a bit fancier here... my $array3ref = \@array3; add_arrayref_to_hashref( $array3ref, \%hash, ${ $array3ref }[1] ); print "\nafter adding array3 using ${ $array3ref }[1]:\n", Dumper( \%h +ash ); sub add_arrayref_to_hashref { my ( $arrayref, $hashref, $key ) = @_; push( @{ ${ $hashref }{$key} }, $arrayref ); }

    OUTPUT:

    after adding array1 using key1: $VAR1 = { 'key1' => [ [ 'one', 'two', 'three' ] ] }; after adding array2 using key1: $VAR1 = { 'key1' => [ [ 'one', 'two', 'three' ], [ 'four', 'five', 'six' ] ] }; after adding array3 using eight: $VAR1 = { 'key1' => [ [ 'one', 'two', 'three' ], [ 'four', 'five', 'six' ] ], 'eight' => [ [ 'seven', 'eight', 'nine' ] ] };

    Update: Ack! I see davidj posted a very similar response while I was composing mine. His uses a slice with your actual data, while mine is more of a general example. Use whichever helps, and enjoy using refs! Extra credit: Instead of passing 3 arguments, you could eliminate the key and simply pass references to the hashref and the desired arrayref, but I'll leave that as an exercise for the reader...

Re: Loading of Complex Data Structures
by talexb (Chancellor) on Aug 25, 2004 at 20:42 UTC

    I can highly recommend Data::Dumper for displaying data structures once you've got the data into variables. You're not there yet, of course, and I'm not getting how your data is supposed to be structured. Can you walk us through how your sample data should be structured, using the data you provided?

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: Loading of Complex Data Structures
by davidj (Priest) on Aug 25, 2004 at 20:29 UTC
    1) What exactly are you passing to insert_carrier_values? What is its structure and content?
    2) From the 2 record sample you gave, what should the data structure data look like?

    davidj

      The $array_ref is the record set. One line of the record set looks like the following:
      ...
      334 Capped 28 5034366 16777215 NULL NULL NULL
      373 Capped 28 5034366 16777215 NULL NULL NULL
      ...
      $hash_ref is an empty hash.

      It should look like:
      Key value = '55034366';
      $VAR148 = [ [ '334', 'Capped ', 28, 16777215, undef, undef ], [ '373 ', 'Capped ', 28, 16777215, undef, undef ], ]
        The following code will do what you want:
        #!/usr/bin/perl use Data::Dumper; my %HoA = (); my %hash_track = (); while(<DATA>) { chomp($_); my (@stuff) = split(" ", $_); &fill(@stuff); } print Dumper(\%HoA); sub fill() { my @a = @_; my @ar = @a[0,1,2,4,5,6,7]; my $h = $a[3]; $HoA{$h}[$hash_track{$h}] = [ @ar ]; $hash_track{$h}++; } __DATA__ 334 Capped 28 5034366 16777215 NULL NULL NULL 373 Capped 28 5034366 16777215 NULL NULL NULL
        output:
        $VAR1 = { '5034366' => [ [ '334', 'Capped', '28', '16777215', 'NULL', 'NULL', 'NULL' ], [ '373', 'Capped', '28', '16777215', 'NULL', 'NULL', 'NULL' ] ] };

        %hash_track is used to increment the first level %HoA array.

        hope this helps,

        davidj