Any number of sets can be passed (not just two or three).
By BK
my @numericUnion = union{ $_[0] == $_[1] } [1,2,3], [2,3,4], [9]; #ret +urns ( 1, 2, 3, 4, 9 ) my @stringUnion = union{ $_[0] eq $_[1] } [ qw( aaa bbb ccc ) ], [ qw( + bbb ccc ddd ) ]; #returns( 'aaa','bbb','ccc','ddd' ) my @unique = union{ $_[0]->isSameNode } [ qw( list of xml nodes ) ], +[ qw( othrer list of xml nodes ) ] #unique node list sub union(&@){ my $eq = shift; @_ == 1 ? @{ $_[0] } : union( $eq, [ @{ $_[0] }, grep &{sub{ !grep $eq->( $_, $_[0] ), @_[1..$#_] }}( $_, @{ $_[0] } ), @{ $_[1] } ], @_[2..$#_] ) }

Replies are listed 'Best First'.
Re: Let's unite sets
by jdporter (Paladin) on Mar 28, 2005 at 21:01 UTC
    I'm not sure what's going on with your "equals" concept there. Why is that approach better than
    sub union { my %h; @h{@$_} = @$_ for @_; values %h }
    ???
      Would your union works for objects?
      my @unique = union{ $_[0]->isSameNode } [ qw( list of xml nodes ) ], [ qw( other list of xml nodes ) ] #unique node list

      Edited by castaway - added code tags

        Certainly. Notice that the hash keys are "stringified objects", which include a memory locations, like this:

        % perl -le 'print bless +{}, "Foo"' Foo=HASH(0x814cbb8)
        So objects are considered equal only if their "stringifications" match. You still recover the original object from the corresponding hash value.

        the lowliest monk

        It would, and does. I encourage you to try it for yourself. I also encourage you to look at existing modules, such as Set::Object, which generally do a lot more than just union.
      are you sure it's @h{@_} not $h{@_}
        Oh, yes, quite sure. It's called a "hash slice". You can look it up. :-)

        In a nutshell: Let's say you have an array @a; then doing

        @h{@a} = @a;
        is the same as doing
        for ( @a ) { $h{$_} = $_; }