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

<HTML> How can I create a hash with 2 key value pairs that also links to an array of data?
I am not sure if this is called a multidimensional hash of arrays.
Upon reading a file I need to compare 2 vaules for example Network and connection type.
If these values do not exist create the new values and store the trailing data with them.
I currently have the following which works with only one key pair, but it is over writing the
previous data because I am only comparing one field:
@str = qw( 7 house network_name 4 6); //<--example of data if($myhash {$str2}}){ // if netowrk_name is found increment the values of 3 and 4 } else{ //must be new so ad new data to hash }
But I need to compare and store 2 results.
example I need to store and compare 0 and 2 and then have that array of data behind it.
Can someone shed some light on this for me?
thanks, Kev
kev@kevintaylor.net </HTML>

Replies are listed 'Best First'.
Re: multidimensional hash of array
by davorg (Chancellor) on May 31, 2001 at 19:18 UTC

    You can get a lot of good advice on complex data structures by reading perldoc perlreftut and perldoc perldsc. Here are some clues:

    @str = qw( 7 house network_name 4 6); #<--example of data if ($myhash{$str[2]}{$str[0]){ # if network_name is found increment the values of 3 and 4 ($myhash{$str[2]}{$str[0]}[3])++; ($myhash{$str[2]}{$str[0]}[4])++; } else { # must be new so ad new data to hash $myhash{$str[2]}{$str[0]} = [ @str ]; }
    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: multidimensional hash of array
by bwana147 (Pilgrim) on May 31, 2001 at 20:06 UTC

    A simple solution is two concatenate the two keys into one with a seldom used character. In fact, that's what Perl does internally when you give several keys to index a hash:

    $myhash{'key1', 'key2'};

    is equivalent to:

    $myhash{join("\x1c", 'key1', 'key2')};

    ASCII 28 is considered a seldom used character, but you may use another one by changing $;.

    Needless to say this is widely considered dirty. davorg's suggestion of using a hash of hashes of arrays is a lot neater.

    HTH

    --bwana147

      I would like to thank everyone for their help
      I currently have:
      foreach(@info){ $_=~ s/^\s+//; @str = split; if( $myhash{$str[2]}{$str[0]} ){ # if same connection type al +ready stored ( $myhash{$str[2]}{$str[0]}[0] ) += $str[0]; ( $myhash{$str[2]}{$str[0]}[1] ) += $str[4]; ( $myhash{$str[2]}{$str[0]}[2] ) += $str[5]; ( $myhash{$str[2]}{$str[0]}[3] ) += $str[6]; ( $myhash{$str[2]}{$str[0]}[4] ) += $str[7]; ( $myhash{$str[2]}{$str[0]}[5] ) += $str[8]; ( $myhash{$str[2]}{$str[0]}[6] ) += $str[9]; ( $myhash{$str[2]}{$str[0]}[7] ) += $str[12]; ( $myhash{$str[2]}{$str[0]}[8] ) += $str[13]; ( $myhash{$str[2]}{$str[0]}[9] ) += $str[16]; } else{# if connection type is not stored push(@temp, $str[0], $str[4], $str[5], $str[6], $str[7], +$str[8], $str[9], $str[12], $str[13], $str[16]); $myhash{$str[2]}{$str[0]} = [@temp]; #enter new data } }

      My next step will be determining how to print, I was using the code below but I will change that
      foreach my $element(sort keys %myhash){ printf OUT ("%-20s", $element); foreach (@{$myhash{$element}}){ printf OUT ("%8s", $_); } print OUT "\n"; }#foreach
      thanks everyone