in reply to Appending values to existing hash key

Arguably more idomatic for the split/join:
$val=~s/\s+/:/g;
But this modifies the $val.

For the second question of appending to hash values, I'd suggest a better structure would be a hash of arrays"

push @{ $hash{$key} }, $v;
That way, you do not need to check for existance - it is auto-vivified.
The difference is - for output, you will have to "join" with $sep:
... output for each $key .... join $sep,@{ $hash{$key} }

        What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
              -Larry Wall, 1992

Replies are listed 'Best First'.
Re^2: Appending values to existing hash key
by jaypal (Beadle) on Mar 21, 2014 at 03:31 UTC

    Thank you for replying so fast. Yes, doing a hash of arrays did occur to me. Something along the lines -

    chomp; (my $k, my @v) = /(\S*\s*\S*\s*)(\S*\s*\S*\s*)/; push @{$h{$k}} , shift @v;

    But dropped the idea because I had to iterate twice:

    foreach my $key (sort keys %h) { print "$key"; foreach my $a (@{$h{$key}}) { print "$a "; } print "\n"; }

    But I see how in a bigger data set this should be the way to go. Checking for existence in a larger hash could be counter productive.

      Hi jaypal,
      i totally agreed with ++NetWallah and really you can use a map for the nested for loop like so:

      use warnings; use strict; my %hash; while (<DATA>) { my @data = split; push @{ $hash{ $data[0] }{ $data[1] } } => "$data[2]: $data[3]"; } for my $key ( sort keys %hash ) { print $key, ' ', join( ', ' => map { $_, @{ $hash{$key}{$_} } } keys %{ $hash{$ke +y} } ), $/; } __DATA__ id1 name1 cat1 catname1 id1 name1 cat2 catname2 id2 name2 cat3 catname3 id3 name3 cat1 catname1 id3 name3 cat4 catname4


      UPDATE: Code updated as indicated by NetWallah.

      If you tell me, I'll forget.
      If you show me, I'll remember.
      if you involve me, I'll understand.
      --- Author unknown to me
        The statement :
        join( ', ' => map { $_, @{ $hash{$key}{$_} } } keys $hash{$key} ), +$/;
        should read:
        join( ', ' => map { $_, @{ $hash{$key}{$_} } } keys %{ $hash{$key} +} ), $/;
        Nice shortcut (++) - nesting the hashes !

                What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                      -Larry Wall, 1992

        Wow, you guys are totally awesome. My first post (albeit lame) has got me so many great tricks and tips. Reading the map function initially from the camel book was a little overwhelming for me. But your usage in an example below has started my brain to make some sense out of it. Another valuable and code shortening gem you have offered is

        push @{ $hash{ $data[0] }{ $data[1] } } => "$data[2]: $data[3]";
        Thank you so much!

      But I see how in a bigger data set this should be the way to go. Checking for existence in a larger hash could be counter productive.

      You probably don't have to worry about that, searches in hashes are fast and usually do not depend on the size of the hashes.