Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Hash of Arrays

by pmilne (Novice)
on Dec 25, 2020 at 21:51 UTC ( [id://11125737]=perlquestion: print w/replies, xml ) Need Help??

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

I can build a hash of arrays using:
push(@{ $hash{"ef56"} }, 2.6, "red", 4);
and I can read or write a single item with (say) $hash{"ef56"}[0]
However I wish to be able to store a list of attributes for each hash - for example: [0] height, [1] color, [2] weight so I can get (say) the color of an item by specifying the hash key and 'color' (in whatever form) rather than having to use [1].

Replies are listed 'Best First'.
Re: Hash of Arrays
by 1nickt (Canon) on Dec 25, 2020 at 22:16 UTC

    So what's the problem you are having? It's not well-stated here. Do you need help on how to use a Hash of Hashes instead?

    use strict; use warnings; use feature 'say'; use Data::Dumper; my %hoh; while (my $line = <DATA>) { chomp($line); my ($key, $height, $color, $weight) = split(' ', $line); @{ $hoh{$key} }{qw/height color weight/} = ($height, $color, $weig +ht); } say Dumper \%hoh; __DATA__ ef56 2.6 red 4 ef42 2.8 green 3
    Output:
    $VAR1 = { 'ef56' => { 'color' => 'red', 'weight' => '4', 'height' => '2.6' }, 'ef42' => { 'height' => '2.8', 'weight' => '3', 'color' => 'green' } };

    Hope this helps!


    The way forward always starts with a minimal test.
Re: Hash of Arrays
by LanX (Saint) on Dec 25, 2020 at 22:39 UTC
    Sounds like you rather want a hash of hashes and you already got the appropriate answer.

    For completeness: if you're stuck with that HoA you can also opt to use constants:

    use constant { height => 0, color => 1 weight=> 2,...}; (untested)

    then you'll be able to access the array members by name.

    $hash{"ef56"}[height]

    If that's also not your question, feel free to clarify.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      pmilne:   To illustrate a couple of variations on hash-of-arrays:

      Win8 Strawberry 5.8.9.5 (32) Fri 12/25/2020 18:25:00 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings use Data::Dumper; use constant { HEIGHT => 0, COLOR => 1, WEIGHT => 2, }; my %HoA; while (<DATA>) { chomp; my ($key, $height, $color, $weight) = split; die "duplicate key '$key'" if exists $HoA{$key}; $HoA{$key} = [ $height, $color, $weight ]; } print Dumper \%HoA; print "'ef56' color is $HoA{'ef56'}[COLOR]"; __DATA__ ef56 2.6 red 4 ef42 2.8 green 3 ^Z $VAR1 = { 'ef56' => [ '2.6', 'red', '4' ], 'ef42' => [ '2.8', 'green', '3' ] }; 'ef56' color is red
      C:\@Work\Perl\monks >perl -Mstrict -Mwarnings use Data::Dumper; use constant { HEIGHT => 0, COLOR => 1, WEIGHT => 2, }; my %HoAoA; while (<DATA>) { chomp; my ($key, $height, $color, $weight) = split; push @{ $HoAoA{$key} }, [ $height, $color, $weight ]; } print Dumper \%HoAoA; print "'ef56' second color is $HoAoA{'ef56'}[1][COLOR]"; __DATA__ ef56 2.6 red 4 ef42 2.8 green 3 ef56 9.8 blue 7 ^Z $VAR1 = { 'ef56' => [ [ '2.6', 'red', '4' ], [ '9.8', 'blue', '7' ] ], 'ef42' => [ [ '2.8', 'green', '3' ] ] }; 'ef56' second color is blue

      Update: See the Perl Data Structures Cookbook (perldsc) for much more on this topic.


      Give a man a fish:  <%-{-{-{-<

Re: Hash of Arrays
by BillKSmith (Monsignor) on Dec 26, 2020 at 00:00 UTC
    If you must use HOA, I prefer to refer to the index with a Readonly variable rather than with a constant because it can interpelate into a string.
    use strict; use warnings; use Readonly; Readonly::Scalar my $COLOR => 1; my %hash = ( ef56 => [], ); push @{ $hash{"ef56"} }, 2.6, "red", 4; print "The color of Item ef56 is $hash{'ef56'}[$COLOR]\n";
    Bill
Re: Hash of Arrays
by jcb (Parson) on Dec 26, 2020 at 01:42 UTC

    Assuming multiple items can be inserted under the same key, you probably want a hash of arrays of hashes. Building this is similar, just push a hashref instead of loose values: (all code untested)

    push @{ $hash{"ef56"} }, {height => 2.6, color => 'red', weight => 4} +; push @{ $hash{"ef56"} }, {height => 3.2, color => 'blue', weight => 5} +;

    This will also allow you to easily iterate over the items associated with any one key:

    foreach my $item (@{$hash{"ef56"}}) { print $item->{height}, ' ', $item->{color}, ' ', $item->{weight}, "\ +n"; }

    See the documentation for more, particularly perldsc, perllol, perlreftut, and perlref.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11125737]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-03-28 08:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found