This is a great idea. In fact, its such a great idea that its been done many times before. :) You've definitely hit on a useful technique.
This is pretty similar to recipe 4.8 in the Perl Cookbook 1st edition.
foreach $e (@a, @b) { $count{$e}++ } foreach $e (keys %count) { push(@union, $e); if ($count{$e} == 2) { push @isect, $e; } else { push @diff, $e; } }
Here's my implementation with each operation calculated separatly.
use strict; use warnings; my @one = qw( 1 2 3 5 6 8 10 ); my @two = qw( 2 4 6 8 10 ); print "One = @one\n"; print "Two = @two\n"; print "\n"; my %union; @union{@one, @two} = (); my @union = sort keys %union; print "Union = @union\n"; my (%one, %two); @one{@one} = (); @two{@two} = (); my %intersection = map { exists $one{$_} && exists $two{$_} ? ($_ => undef) : () } @one, @two; my @intersection = sort keys %intersection; print "Intersection = @intersection\n"; my %one_minus_two = map { exists $two{$_} ? () : ($_ => undef) } @one; my @one_minus_two = sort keys %one_minus_two; print "One - Two = @one_minus_two\n"; my %symdiff = map { 1 == ( exists($one{$_}) + exists($two{$_}) ) ? ($_ => undef) : () } @one, @two; my @symdiff = sort keys %symdiff; print "Symdiff = @symdiff\n";
If I was doing a whole lot of set manipulation I'd look for a library that provides a complete suite of set theoretic operations--like Set::Object or Set::Scalar. For simple uniqueness, I'd probably stick with List::MoreUtils--some of its other functions like 'any' and 'all' offer such great readability improvements to my code that I have come to rely on it.
TGI says moo
In reply to Re: Idiom: hashes as sets
by TGI
in thread Idiom: hashes as sets
by vrk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |