Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

multiple values for one key in hash

by sovixi (Novice)
on May 12, 2008 at 21:37 UTC ( [id://686151]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks, Is there any chance I can assign multiple values to one key in a hash? Thanks

Replies are listed 'Best First'.
Re: multiple values for one key in hash
by kyle (Abbot) on May 12, 2008 at 21:45 UTC

    No, but you can make the one value for a key be a reference to an array which contains multiple values.

    $h{key} = [ 'value1', 'value2' ]; push @{ $h{key} }, 'value3', 'value4'; # $h{key}->[2] eq 'value3' # ${ $h{key} }[3] eq 'value4'

    If you're not familiar with array references, see perlreftut for a start.

    You can also make the one value for a key be a string that encodes all the various values (e.g., CSV or Data::Dumper output, etc.)

      #!/usr/bin/perl %hash=(); $key = "SingleKey"; @A = ("Many","Value"); foreach $v (@A){ chomp($v); #$hash{$key}=join("|",$hash{$key},$v); $hash{$key}="$hash{$key}"."$v"; } while (($K,$V)=each(%hash)){ print"$K->$V\n"; }
Re: multiple values for one key in hash
by Fletch (Bishop) on May 12, 2008 at 21:41 UTC

    Nope. One slot in a hash holds one scalar value.

    The trick is to use a scalar value that can hold more than one value instead. See perldsc and perlreftut.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: multiple values for one key in hash
by wade (Pilgrim) on May 12, 2008 at 22:04 UTC

    How about using a reference to an array. Here's a little ditty that builds the kind of hash for which you're looking and then prints out the results:

    use strict; use warnings; use diagnostics; use Data::Dumper; my %hash; my $key; my $value; my @data = ("foo",1, "bar",2, "foo",3, "baz",4); while ($key = shift (@data)) { $value = shift (@data); # push the value on the array push @{$hash{$key}}, $value; } print Dumper \%hash;

    Note: you have to create the anonymous reference -- you can't just push a value if the key doesn't exist.

    Update: apparently you can just push the value.

    --
    Wade
      Note: you have to create the anonymous reference -- you can't just push a value if the key doesn't exist.

      In perl you can ;-)

      use strict; use warnings; use Data::Dumper; my %hash; push @{$hash{key}}, 'value'; print Dumper \%hash; __END__ $VAR1 = { 'key' => [ 'value' ] };

      This nice feature is called "autovivification" and is quite useful most of the time.

        Son of a gun! You can just push the value. I could have sworn that this didn't work when I tried it at my old job (about 2 years ago). Is this a feature that has happened since then or have I been brain dead all this time?

        Thanks, moritz; ++

        --
        Wade
Re: multiple values for one key in hash
by Anonymous Monk on Feb 25, 2015 at 17:29 UTC

    I was just asking myself this same question. While I'm sure most of the comments below work just fine, I'd like to add my solution as well.

    I just separated the "values" by a comma, and have a single "value" related to the key in my hash.

    When I read out the key value, I'll just do a split on the value in order to break it up in to the individual data points I need.

    This is simple, and very readable/easy to understand for someone who is not quite a perl monk like me.
      Seems valid to me, at least as long as you're looking at a small number of vals, but as always TMTOWTDI.
Re: multiple values for one key in hash
by Anonymous Monk on Nov 08, 2012 at 09:14 UTC
    how can i get the count of value array(multiple values are stored as an array) here?

      Just dereference the array in a scalar context:

      #! perl use strict; use warnings; my %families = (Flintstone => [ qw(Pebbles) ], Simpson => [ qw(Bart Lisa Maggie) ], Keaton => [ qw(Alex Mallory Jennifer Andy) ]); for my $name (keys %families) { my $num_children = @{ $families{$name} }; # <-- Here's where it + happens if ($num_children == 1) { print "There is $num_children child in the $name family\n"; } else { print "There are $num_children children in the $name family\n" +; } }

      Hope that helps,

      Athanasius <°(((><contra mundum

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-03-28 08:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found