Coder Perfect

Intersect’s polar opposite ()

Problem

Intersect can be used to find matches between two collections, like so:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call Intersect extension method.
var intersect = array1.Intersect(array2);
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 2, 3
}

However what I’d like to achieve is the opposite, I’d like to list items from one collection that are missing from the other:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call "NonIntersect" extension method.
var intersect = array1.NonIntersect(array2); // I've made up the NonIntersect method
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 4
}

Asked by Peter Bridger

Solution #1

As previously indicated, if you wish to get a 4 as a result, you can do as follows:

var nonintersect = array2.Except(array1);

If you want the true non-intersection (which includes both 1 and 4), try this:

var nonintersect = array1.Except(array2).Union( array2.Except(array1));

This will not be the most efficient option, but it should suffice for tiny lists.

Answered by Øyvind Bråthen

Solution #2

You can use

a.Except(b).Union(b.Except(a));

You can also make advantage of

var difference = new HashSet(a);
difference.SymmetricExceptWith(b);

Answered by sehe

Solution #3

This code enumerates each sequence only once and uses Select(x => x) to hide the result to get a clean Linq-style extension method. Since it uses HashSet its runtime is O(n + m) if the hashes are well distributed. Duplicate elements in either list are omitted.

public static IEnumerable<T> SymmetricExcept<T>(this IEnumerable<T> seq1,
    IEnumerable<T> seq2)
{
    HashSet<T> hashSet = new HashSet<T>(seq1);
    hashSet.SymmetricExceptWith(seq2);
    return hashSet.Select(x => x);
}

Answered by CodesInChaos

Solution #4

I think you might be looking for Except:

Check out this link, this link, or Google, for more information.

Answered by Grant Thomas

Solution #5

array1.NonIntersect(array2);

Linq doesn’t have a nonintersect operator, thus you’ll have to make one.

if -> if -> if -> if -> if ->

a.except(b).union(b.Except(a));

Answered by safder

Post is based on https://stackoverflow.com/questions/5620266/the-opposite-of-intersect