The opposite of Intersect()
Solution 1
As stated, if you want to get 4 as the result, you can do like this:
var nonintersect = array2.Except(array1);
If you want the real non-intersection (also both 1 and 4), then this should do the trick:
var nonintersect = array1.Except(array2).Union( array2.Except(array1));
This will not be the most performant solution, but for small lists it should work just fine.
Solution 2
You can use
a.Except(b).Union(b.Except(a));
Or you can use
var difference = new HashSet(a);
difference.SymmetricExceptWith(b);
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<T>
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);
}
Solution 4
I think you might be looking for Except
:
The Except operator produces the set difference between two sequences. It will only return elements in the first sequence that don't appear in the second. You can optionally provide your own equality comparison function.
Check out this link, this link, or Google, for more information.
Solution 5
array1.NonIntersect(array2);
Nonintersect such operator is not present in Linq you should do
except -> union -> except
a.except(b).union(b.Except(a));
Related videos on Youtube
Peter Bridger
Technical Architect at Zone (https://www.thisiszone.com/) instilling the benefits of TDD and SOLID within the teams I run and using Scrum and a Continuous Delivery pipeline to continuously deliver high quality software
Updated on September 21, 2020Comments
-
Peter Bridger over 3 years
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 }
-
Øyvind Bråthen about 13 yearsplease confirm if you want 4 as the output, or 1 and 4
-
Peter Bridger about 13 years@oyvind-knobloch-brathen Yes, I would only like 4
-
Mike T almost 12 yearsAs a side note, this type of set is called a Symmetric Difference.
-
rtorres almost 10 yearsTechnically speaking, a Symmetric Difference would result into [1, 4]. Since Peter wanted just the elements in array2 that are not in array1 (i.e., 4), that's called a Relative Complement (aka Set-Theoretic Difference)
-
-
Peter Bridger about 13 yearsInteresting use of SymmetricExceptWith(), I wouldn't have thought of that approach
-
shanabus over 12 yearswhat would be a better performing solution? Thanks!
-
Øyvind Bråthen over 12 yearsYou can probably do it faster by using two nested for loops, but the code will be way dirtier than this. Counting readability into this also, I would clearly use this variant as it's very easy to read.
-
Ash Clarke about 11 years
SymmetricExceptWith
is probably my favourite method. -
Dan about 11 yearsI compared the two in a real application where I had a couple lists of about 125 strings in each of them. Using the first approach is actually faster for lists of that size, though its mostly insignificant as both approaches where under half a millisecond.
-
Dwighte almost 11 yearsJust a sideline point to add, If you have: int[] before = { 1, 2, 3 }; int[] after = { 2, 3, 3, 4 }; and you try to use Except to find what's been added to 'after' since 'before': var diff = after.Except(before); 'diff' contains 4, not 3,4. i.e. watch out for duplicate elements giving you unexpected results
-
Drew Noakes almost 9 yearsWould be nice if the BCL had a Linq extension method for this. It seems like an omission.
-
Colin almost 7 yearsSomeone benchmarked SymmetricExceptWith and found it much faster: skylark-software.com/2011/07/linq-and-set-notation.html
-
LBW about 6 yearsWould this perform better? array1.AddRange(array2.Except(array1));
-
amuliar over 5 yearsIntersection of sets == A∪B\A∩B
-
TheHunter Shergill over 2 years@ØyvindBråthen thank you it helped a lot.
-
Filimindji over 2 yearsI like the extension method, but I'm not sure about the .Select(x => x). Don't you think it add some unnecessary overhead ?