Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re: Merge hash into another hash

by ides (Deacon)
on Apr 29, 2007 at 15:19 UTC ( #612647=note: print w/replies, xml ) Need Help??

in reply to Merge hash into another hash

That works great for simple hashes, but if you have a complex data structure you'll definitely want to check out Hash::Merge

Frank Wiles <>

Replies are listed 'Best First'.
Re^2: Merge hash into another hash
by naikonta (Curate) on Apr 30, 2007 at 01:41 UTC
    This is what I would definitely use for complex structure, as I would have different rules for certain keys at different depth levels.

    As for simple merge, I tend to use the opposite of what GrandFather uses. My target hashes are mostly new initialized ones, and the the source is taken as custom values that override the default. So I just stuff source into target. Because the source hash is actually a reference, it will be dereferenced.

    sub some_meth { my($self, $source) = @_; my %target = ( key1 => 'default_1', key2 => 'default_2', keyN => 'default_N', %$source, ); # do somethings with %target }
    Of course, GrandFather's technique can be applied as well. And I can see an advantage to have a chance to check the source prior to merging.
    my %target = ( # initialization ); %target{keys %$source} = values %$source if defined $source && ref $source eq 'HASH';

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

      For simple hashes, what's wrong with just:

      my %target = ( #initialize ); %target = (%target, %source)
      ? (with the issues of complex cases, source checking, and dereferencing aside (but perhaps fixable))


        Hi, let me try to explain with my limited knowledge of perl's internal behaviour ;o)

        Your solution converts %target and %source into flat lists, combines it to one list and assigns that list to %target...

        Grandfather's solution only inserts the key-value pairs from %source into %target, overwriting already existing pairs.

        This is less expensive than converting into lists and reassigning these lists.

        I tried a benchmark which shows that Grandfather's solution is faster than yours.

        I have to admit, that - until this post - I preferred and used the way you presented (mainly because of readability), but now I have to reconsider ;o)

        #!/usr/bin/perl # vim: set ts=4 sw=4 et sta: use strict; use warnings; use Benchmark qw( cmpthese ); my %target; my %source; ## prefill @target{'aa'..'zz' } = 'aa' .. 'zz'; @source{'ww'..'yy', 1..100} = ( 'ww'..'yy', 1..100 ); cmpthese( -1, { grandfather => sub { my %t = %target; @t{keys %source} = values %source; }, sleepyjay => sub { my %t = %target; %t = ( %t, %source ); }, }); __END__ Rate sleepyjay grandfather sleepyjay 598/s -- -62% grandfather 1585/s 165% -- Rate sleepyjay grandfather sleepyjay 649/s -- -62% grandfather 1706/s 163% --

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://612647]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2018-05-26 08:41 GMT
Find Nodes?
    Voting Booth?