sathiya.sw has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I would want to merge two hashes, and then update the 1st hash keys with the 2nd hash values of the non-unique keys. To be clear..
%hash1 = ( a, b, c, d, e, f ); %hash2 = ( a, J, e, K ); use Data::Dumper; print Dumper ( \%hash1 ); print Dumper ( \%hash2 ); # WHAT TO DO HERE TO GET UPDATED VALUES ?? print "=========AFTER===========\n"; print Dumper ( \%hash1 ); #print Dumper ( \%hash2 );
Output should be like...
$VAR1 = { 'e' => 'f', 'c' => 'd', 'a' => 'b' }; $VAR1 = { 'e' => 'K', 'a' => 'J' }; =========AFTER=========== $VAR1 = { 'e' => 'K', 'c' => 'd', 'a' => 'J' };
I had the following ways of doing it...

The first way seems promising as i have the requirement of only the first hash keys remain as it is, where as the 2nd way shown here will put the 2nd hash sets unique keys also into the 1st hash.

Question is
I would not want to run over all the hash keys and then do this operation ?! Do you have any single liner, or some statement which can do this operation smarter ?

Sathiyamoorthy

Replies are listed 'Best First'.
Re: merging two hashes and updating the 1st hash keys.
by moritz (Cardinal) on Aug 27, 2009 at 11:29 UTC
    You have to use the whole of the second hash somehow, either implicitly by saying %hash1 = ( %hash1, %hash2 ); or explicitly by looping. There's no way around looking at each item of the second hash.

    So what's wrong with looping over %hash2 and updating %hash1 as you go along?

    Perl 6 - links to (nearly) everything that is Perl 6.
Re: merging two hashes and updating the 1st hash keys.
by roboticus (Chancellor) on Aug 27, 2009 at 12:29 UTC
    sathiya.sw:

    I think this is what you want:

    # cat 791596.pl use strict; use warnings; use Data::Dumper; my %h1 = ( e=>'f', c=>'d', a=>'b' ); my %h2 = ( e=>'K', a=>'J', q=>'V' ); do { my @b = grep {exists $h1{$_}} keys %h2; @h1{@b} = @h2{@b}; }; print Dumper(\%h1); # perl 791596.pl $VAR1 = { 'e' => 'K', 'c' => 'd', 'a' => 'J' };

    The first hash is updated with the values from the second, but no new keys (such as q in the second hash) are added to the first hash.

    ...roboticus

    Update: Correction as per Gramps' reply. ;^)

      Use of exists in the grep, not defined may be clearer. defined implies that there is an element in %h1 that matches the key, but that it may be undef. exists tests for the existence of the element with no implication that it should already be there or that it may be set to any particular value.

      It's interesting to note though that defined doesn't cause elements in %h1 to be autovified as might be expected.


      True laziness is hard work
Re: merging two hashes and updating the 1st hash keys.
by Anonymous Monk on Aug 27, 2009 at 11:35 UTC
    where as the 2nd way shown here will put the 2nd hash sets unique keys also into the 1st hash.

    use the 2nd way, your example shows that is what you want.

      If am not clear already !

      ---> The first way seems promising as i have the requirement of only the first hash keys remain as it is, where as the 2nd way shown here will put the 2nd hash sets unique keys also into the 1st hash.

      I wanted something like the first way, because i would want the first hash keys remain as it is... I don't want the second hash's unique keys to be added to the 1st hash. But the result i want is like the 1st way i shown, but not as with the same kind of looping implementation.
      Sathiyamoorthy
Re: merging two hashes and updating the 1st hash keys.
by BrowserUk (Patriarch) on Aug 28, 2009 at 07:21 UTC

    This achieves your goal. But it still loops, albeit that the loop is hidden:

    %hash1 = qw( a b c d e f ); %hash2 = qw( a J e K y z ); @sharedKeys = grep defined( $hash2{ $_ } ), keys %hash1; @hash1{ @sharedKeys } = @hash2{ @sharedKeys };; print %hash1;; e K c d a J

    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".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: merging two hashes and updating the 1st hash keys.
by bichonfrise74 (Vicar) on Aug 27, 2009 at 22:04 UTC
    Another way of doing it.
    #!/usr/bin/perl use strict; my %hash_1 = ( 'a' => 'b', 'c' => 'd', 'e' => 'f' ); my %hash_2 = ( 'a' => 'J', 'e' => 'K' ); my %new_hash; $new_hash{$_} = $hash_2{$_} ? $hash_2{$_} : $hash_1{$_} for keys %hash_1; print map { $_ => " => " . $new_hash{$_} . "\n" } keys %new_hash;
      Yeah this way works !! But as i told in the question, i dont want to iterate over each hash element and am looking for a smarter way ! Anyway thanks for your response..
      Sathiyamoorthy