use strict; use warnings; # Create two test hashes, with some matching keys, and some keys only in # the first or second hash. # my %hash1 = ( 'a' => 1, 'b' => 2, 'd' => 3, 'f' => 4, 'h' => 5 ); my %hash2 = ( 'a' => 1, 'c' => 2, 'd' => 3, 'e' => 5, 'g' => 6 ); # Get the union of the two hashes, and save it in an array (@union) my %union = map { $_ => 1 } (keys %hash1, keys %hash2); my @union = keys %union; # Declare arrays for values only in %hash1, values only in %hash2, and # values found in both (the intesection). ## my (@hash1, @hash2, @inter); # For each item in the intersection, construct a flag which identifies # which array to save it in. # foreach (@union) { my $flag = (exists $hash1{$_}? 1: 0) + (exists $hash2{$_}? 2: 0); (1 == $flag) and push @hash1, $_; (2 == $flag) and push @hash2, $_; (3 == $flag) and push @inter, $_; } # Display the results print "[Results]\n"; printf "Union ........... %s\n", join(',', sort @union); printf "Intersection .... %s\n", join(',', sort @inter); printf "Only in hash1 ... %s\n", join(',', sort @hash1); printf "Only in hash2 ... %s\n", join(',', sort @hash2); __DATA__ [Results] Union ........... a,b,c,d,e,f,g,h Intersection .... a,d Only in hash1 ... b,f,h Only in hash2 ... c,e,g