in reply to merge two hashes into one

map is useful here. The following example assumes that keys in both hashes are the same; ie. %h2 does not have any extra keys that %h1 doesn't have.

use strict; use Data::Dumper; my %h1 = (a => 1, b => 2, c => 3); my %h2 = (a => 6, b => 8, c => 0); my %h3 = map {$_ => $h1{$_} + $h2{$_}} keys %h1; print Dumper \%h3;

Output:

$VAR1 = { 'c' => 3, 'b' => 10, 'a' => 7 };

If %h2 does have keys that %h1 doesn't have, change this line:

my %h3 = map {$_ => $h1{$_} + $h2{$_}} keys %h1;

...to this:

my %h3 = map {$_ => $h1{$_} + $h2{$_}} keys %h1, keys %h2;

Replies are listed 'Best First'.
Re^2: merge two hashes into one
by AnomalousMonk (Archbishop) on May 30, 2018 at 01:23 UTC

    map could also be used to generate the sums of the intersection set of the two hashes (with no exceptions thrown):

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my %h1 = qw(a 1 b 2 c 3 ); my %h2 = qw( b 7 c 8 d 4); ;; my %h_out = map exists $h2{$_} ? ($_ => $h1{$_} + $h2{$_}) : (), keys %h1 ; dd \%h_out; " { b => 9, c => 11 }
    The exists test could be moved into a separate grep step for perhaps greater clarity, but I'd expect a bit of a performance hit with large hashes.

    BTW: Won't
        my %h3 = map {$_ => $h1{$_} + $h2{$_}} keys %h1, keys %h2;
    cause "Use of uninitialized value ..." warnings unless that warning is disabled?


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

      my %h1 = qw( a 1 b 2 c 3 ); my %h2 = qw( b 7 c 8 d 4 ); my %h3 = map { $_ => $h1{$_} // 0 + $h2{$_} // 0 } keys %h1, keys %h2;

      No warnings, merges both hashes


      Enjoy, Have FUN! H.Merijn

        The expression  $h1{$_} // 0 + $h2{$_} // 0 has a complicated precedence:

        c:\@Work\Perl\monks>perl -wMstrict -MO=Deparse,-p -le "my %h1 = qw( a 1 b 2 c 3 ); my %h2 = qw( b 7 c 8 d 4 ); my %h3 = map { $_ => $h1{$_} // 0 + $h2{$_} // 0 } keys %h1, keys %h2 +; " BEGIN { $^W = 1; } BEGIN { $/ = "\n"; $\ = "\n"; } use strict 'refs'; (my(%h1) = ('a', '1', 'b', '2', 'c', '3')); (my(%h2) = ('b', '7', 'c', '8', 'd', '4')); (my(%h3) = map({($_, (($h1{$_} // (0 + $h2{$_})) // 0));} keys(%h1), k +eys(%h2))); -e syntax OK
        Are you sure it works in all circumstances? Wouldn't it be better to throw in a couple pair disambiguating parentheses? E.g.:
            ($h1{$_} // 0) + ($h2{$_} // 0)


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