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

I need a function which takes two hash references as an input and outputs a hash reference, which has all the keys that are unique to one of the inputs and in the case of common keys the value belonging to the second one overwrites the first one. Of course I could iterate over the keys, but in the case of nested structures this has to be recursive. The whole thing gets very complicated and presumably slow. Is there an optimized solution to this problem?
my $ref1= { ref1_specific_key => 'some value', common_key => { ref1_specific_subkey => 'some sub value', common_subkey => 'foo' } }; my $ref2= { ref2_specific_key => 'some other value', common_key => { ref2_specific_subkey => 'some other sub value', common_subkey => 'bar' } }; my $output= { ref1_specific_key => 'some value', ref2_specific_key => 'some other value', common_key => { ref1_specific_subkey => 'some sub value', ref2_specific_subkey => 'some other sub value', common_subkey => 'bar' } };

Replies are listed 'Best First'.
Re: What is the easiest way to merge two hashes?
by Corion (Patriarch) on Feb 15, 2015 at 08:11 UTC

    Just assign the two hashes in the order. Last key wins:

    my %result= (%hash1, %hash2);

    If you have hash references and want to return a hash reference, just do that. tye's References Quick Reference tells you how to get from a reference to a hash.

      For the unnested case this code can determine the joined set of keys of two hash references given the keys of the two hash references separately:
      use Data::Dumper; my $hash1 = { common_key => 'foo', hash1_specific_key => 'some value' }; my $hash2 = { common_key => 'bar', hash2_specific_key => 'some other value' }; my $joined_keys = [ keys( %{ { map { $_=>undef } keys( %{$hash1} ) , keys( %{$hash2} ) } } ) ]; print Data::Dumper->Dump([$joined_keys],['joined keys']);
      Outputs:
      $joined keys = [ 'hash2_specific_key', 'common_key', 'hash1_specific_key' ];
        this code can determine the joined set of keys of two hash references given the keys of the two hash references separately

        So does this, rather more simply:

        sub mergedHashKeys{ my( $r1, $r2 ) = @_; my %h = ( %{ $r1 }, %{ $r2 } ); return [ keys %h ]; };; $hash1 = { common_key => 'foo', hash1_specific_key => 'some value' };; $hash2 = { common_key => 'bar', hash2_specific_key => 'some other value' };; pp mergedHashKeys( $hash1, $hash2 );; ["hash2_specific_key", "common_key", "hash1_specific_key"]

        Or if you are into programming in hieroglyphics, just:

        sub mergedHashKeys{ [ keys %{{ %{ $_[0] }, %{ $_[1] } }} ] };;

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
      Does this work for nested structures?
      my $ref1= { ref1_specific_key => 'some value', common_key => { common_subkey => 'foo'; } }; my $ref2= { ref2_specific_key => 'some other value', common_key => { common_subkey => 'bar'; } }; my $output= { ref1_specific_key => 'some value', ref2_specific_key => 'some other value', common_key => { common_subkey => 'bar'; } };

        No.

        Then, the most easy way is to use Hash::Merge or alternatively, implement it yourself by iterating over the keys.

        Yes, it does. But why did you not try yourself????

        use strict; use warnings; use Data::Dumper; my $ref1= { ref1_specific_key => 'some value', common_key => { common_subkey => 'foo' } }; my $ref2= { ref2_specific_key => 'some other value', common_key => { common_subkey => 'bar' } }; my $output = { %$ref1, %$ref2 }; print Dumper $output;

        Of course, in a more complex example it might not work as expected. But the example you show works ok.

Re: What is the easiest way to merge two hashes?
by i5513 (Pilgrim) on Feb 15, 2015 at 09:23 UTC
        Thank you for your pointer to backcpan, I did not know it. I would not recommend such Module if I would know about backcpan before I write that comment