Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Merge Multiple Hashes

by shotgunefx (Parson)
on Sep 10, 2002 at 13:37 UTC ( #196663=snippet: print w/replies, xml ) Need Help??
Description: Answer to this node. Merges multiple hashes recursively.
Usage: $href = mergehashes(\%h1,%h2,%h3);
Keys' values are turned into an array ref. Any key that has a single non-ref value will be converted back to a scalar.
Dies on circular references. (This is a feature)
#!/usr/bin/perl -w

use warnings; 
use strict;

BEGIN {
        my %SeenMerged = ();

        sub mergehashes{     # Dies on circular references
            my @hashrefs = @_;
            die "Passed a non hashref" if grep { ref $_ ne 'HASH' } @h
+ashrefs;
            my %merged = ();

            my @seen = grep { ref $_ eq 'HASH' }  @SeenMerged{@hashref
+s}; # Break circular links..

            if (@seen){
                die "contains a circular reference! bailing...";
            }

            @SeenMerged{@hashrefs} = @hashrefs;

            foreach my $h (@hashrefs){
                while (my ($k,$v) = each %$h ){
                    push @{$merged{$k}}, $v;
                }
            }

            while (my ($k,$v) = each %merged){
                my @hashes = grep { ref $_ eq 'HASH' } @$v;
                $merged{$k} = $v->[0] if (@$v == 1 && !ref $v->[0]);  
+  
                $merged{$k}  = mergehashes(@hashes) if @hashes;
            }

            delete @SeenMerged{@hashrefs};
            return \%merged;
        }

}

# EXAMPLE

use Data::Dumper;

my (%hash1,%hash2);
%hash1 = (
          red => 1,
          brown => {
                    green => 1,
                    blue => {
                             yellow => 1,
                            },
                    black => 1,
                   },
          gray => 1,
		  
         );

%hash2 = (
          white => 1,
          brown => {
                    purple => 1,
                   },
         );



my $merged = mergehashes(\%hash1, \%hash2 );

print Dumper($merged);


__END__
outputs

$VAR1 = {
          'gray' => 1,
          'white' => 1,
          'brown' => {
                       'blue' => {
                                   'yellow' => 1
                                 },
                       'purple' => 1,
                       'green' => 1,
                       'black' => 1
                     },
          'red' => 1
        };
Replies are listed 'Best First'.
Re: Merge Multiple Hashes
by blakem (Monsignor) on Sep 10, 2002 at 18:02 UTC
Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://196663]
help
Chatterbox?
NodeReaper hides the Vote Fairy's wand

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (2)
As of 2018-05-21 00:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?