Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I have two arrays @a and @b.

@a = (1, 2, 3, 4, 5, 6); @b = ( 3, 4 , 5, 6, 7, 8);

If i find the difference i am getting 1 , 7, 8.

I tried using Set::Scalar.

But what i want is, only the new elements in @b from other than @a. For example in the above arrays, i need only 7 and 8 not 1, 7, 8.

Replies are listed 'Best First'.
Re: array difference
by bobf (Monsignor) on Apr 28, 2005 at 04:13 UTC

    Yet another way, using List::Compare:

    use strict; use warnings; use List::Compare; my @a = (1, 2, 3, 4, 5, 6); my @b = ( 3, 4 , 5, 6, 7, 8); my $lc = List::Compare->new( \@a, \@b ); my @a_only = $lc->get_Lonly; my @b_only = $lc->get_Ronly; print join( ', ', @a_only ), "\n"; # 1, 2 print join( ', ', @b_only ), "\n"; # 7, 8

    This type of question is asked frequently. You can SuperSearch for other threads, such as most efficient way to implement "A without B", and search CPAN for modules in the List:: namespace.

    HTH

Re: array difference
by Fletch (Bishop) on Apr 28, 2005 at 04:03 UTC
    my %in_a; @in_a{ @a } = (1) x @a; my @only_b = grep !exists $in_a{ $_ }, @b;
Re: array difference
by davido (Cardinal) on Apr 28, 2005 at 04:06 UTC

    Try this:

    my @a = ( 1, 2, 3, 4, 5, 6 ); my @b = ( 3, 4, 5, 6, 7, 8 ); my %a_lookup; @a_lookup{@a} = (); my @b_only = grep { not exists $a_lookup{$_} } @b; print "@b_only\n";

    If my calculations are correct, this ought to do the trick. ;)

    Update: Whenever I see a question like this I think to myself, "That sounds like something Quantum::Superpositions could do with grace and ease. While it's true that the Damian's module does accomplish this task simply and easily, it took a conversation in the Chatterbox with tye and merlyn before the actual solution became apparent to me. Credit merlyn for coming up with the Quantum::Superpositions solution at first guess... for my part, I just started the conversation rolling until an expert could come along and get it right. ;)

    use Quantum::Superpositions; my @a = ( 1 .. 6 ); my @b = ( 3 .. 8 ); print "$_\n" foreach eigenstates( any( @b ) != all( @a ) );

    Beauty is in the eye of the beholder, but to my mind's eye that's beautiful. Unfortunately, its simplicity is critically deceptive; don't try this with lists of a thousand elements. Using quantum superpositions on large sets becomes breathtakingly inefficient.


    Dave

Re: array difference
by Errto (Vicar) on Apr 28, 2005 at 04:07 UTC
    One easy way to do it is to use a hash:
    my %tmp; @tmp{@b} = (); delete @tmp{@a}; @result = keys %tmp;
    But this assumes you don't care about the result being in the same order as @b. If @b is already sorted, you can get around that by throwing a sort in front of keys %tmp, though this is somewhat wasteful.

    Update: Sheesh, I guess I'm a little slow at writing nodes. I swear those first two replies weren't there before :)

Re: array difference
by gube (Parson) on Apr 28, 2005 at 07:09 UTC

    Hi try this with set::Scalar module,

    use Set::Scalar; @a = (1, 2, 3, 4, 5, 6); @b = ( 3, 4 , 5, 6, 7, 8); $a = Set::Scalar->new(@a); $b = Set::Scalar->new(@b); print $b->difference($a);
    o/p: (7 8)

    Regards,
    Gubendran.L

Re: array difference
by Mati the Perl Lover (Initiate) on Nov 25, 2011 at 17:58 UTC
    Hi little friends!

    I spent the last six weekends, and I haven't been with a girl in six months, but i finally come up with an easy answer to this problem (with the help of my brilliant super cool stud friend Gary G)

    my @arr1 = (1,2,3,4,5,6,7,8,9); my @arr2 = (4,5,10);

    my @arr3 = grep{my $element = $_; grep ($_ eq $element,@arr2) == 0} @arr1;

    Wich gives (1,2,3,6,7,8,9)

    Kisses to all the monks out there
    Bye
Re: array difference
by NateTut (Deacon) on Apr 28, 2005 at 14:33 UTC
    This topic reminds me of set theory stuff, which I use a lot in SQL. Has anyone implemented array set functions (i.e. intersect, union, etc.) in a module anywhere?
A reply falls below the community's threshold of quality. You may see it by logging in.