use strict; use warnings; sub relative_complement { return list_2_hashref( grep !exists $_[ 1 ]->{ $_ }, keys %{ $_[ 0 ] } ); } sub list_2_hashref { return +{ map +( $_ => 1 ), @_ }; } my $diff = relative_complement( list_2_hashref( @A ), list_2_hashref( @B ) ); #### sub intersection { my %tally; $tally{ $_ }++ for map keys %$_, @_; return list_2_hashref( grep $tally{ $_ } == @_, keys %tally ); } #### sub sym_diff { my %tally; $tally{ $_ }++ for map keys %$_, @_[0, 1]; return list_2_hashref( grep $tally{ $_ } == 1, keys %tally ); } #### my $A = list_2_hashref( qw( a b c ) ); my $B = list_2_hashref( qw( b c d ) ); my $C = list_2_hashref( qw( c d e ) ); $| = 1; use Dumpvalue; my $dumper = Dumpvalue->new(); print "\nA:\n"; $dumper->dumpValue( $A ); print "\nB:\n"; $dumper->dumpValue( $B ); print "\nC:\n"; $dumper->dumpValue( $C ); print "\nrelative complement A, B:\n"; $dumper->dumpValue( relative_complement( $A, $B ) ); print "\nintersection A, B, C:\n"; $dumper->dumpValue( intersection( $A, $B, $C ) ); print "\nsymmetric difference A, B:\n"; $dumper->dumpValue( sym_diff( $A, $B ) ); __END__ A: 'a' => 1 'b' => 1 'c' => 1 B: 'b' => 1 'c' => 1 'd' => 1 C: 'c' => 1 'd' => 1 'e' => 1 relative complement A, B: 'a' => 1 intersection A, B, C: 'c' => 1 symmetric difference A, B: 'a' => 1 'd' => 1 #### use strict; use warnings; use Set::Scalar; my $A = Set::Scalar->new( qw( a b c ) ); my $B = Set::Scalar->new( qw( b c d ) ); my $C = Set::Scalar->new( qw( c d e ) ); print "A: ", $A->as_string, "\n"; print "B: ", $B->as_string, "\n"; print "C: ", $C->as_string, "\n"; print "relative complement A, B: ", $A->difference( $B )->as_string, "\n"; print "intersection A, B, C: ", $A->intersection( $B, $C )->as_string, "\n"; print "symmetric difference A, B: ", $A->symmetric_difference( $B )->as_string, "\n"; __END__ A: (a b c) B: (b c d) C: (c d e) relative complement A, B: (a) intersection A, B, C: (c) symmetric difference A, B: (a d)