Summary: in this tutorial, you will learn how to use the LINQ Except()
method to retrieve the elements from one sequence that are not present in another sequence.
Introduction to the LINQ Except() method
The LINQ Except()
method allows you to get the elements from the first sequence that are not in the second sequence. It returns a new sequence with the type IEnumerable<T>
that contains these elements.
Here’s the syntax of the LINQ Except()
method:
IEnumerable<TSource> Except<TSource> (
this IEnumerable<TSource> first,
IEnumerable<TSource> second
);
Code language: C# (cs)
The Except()
method accepts two parameters first
and second
that have the IEnumerable<T>
type.
The Except()
method returns elements in first
that don’t appear in the second
but not vice versa. In other words, it doesn’t return elements in second
, but don’t appear in first
. Also, it returns only unique elements.
By default, the Except()
method compares the elements in the sequences by their references if they are objects, or by their value if they are primitive types.
To override the default equality comparer, you implement a custom IEqualityComparer<T>
and pass it to the Except()
method:
IEnumerable<TSource> Except<TSource> (
IEnumerable<TSource> first,
IEnumerable<TSource> second,
IEqualityComparer<TSource>? comparer
);
Code language: C# (cs)
In this syntax, you define a class that implements the IEqualityComparer
interface and pass it to the Except()
method.
LINQ Except() method examples
Let’s take some examples of using the LINQ Except()
method.
1) Using LINQ Except() method with a list of integers
The following example uses the Except()
method to return the numbers from the first list that are not present in the second list:
using static System.Console;
var numbers1 = new List<int>() { 1, 2, 3, 4 };
var numbers2 = new List<int>() { 1, 2 };
var numbers = numbers1.Except(numbers2);
foreach (var number in numbers)
{
WriteLine(number);
}
Code language: C# (cs)
Output:
3
4
Code language: C# (cs)
2) Using LINQ Except() method with a list of strings
The following example uses the Except()
method to return elements of the first list but are not in the second list:
using static System.Console;
var fruits1 = new List<string>()
{
"Apple",
"Orange",
"Banana",
"Strawberry"
};
var fruits2 = new List<string>()
{
"Banana",
"Strawberry"
};
var fruits = fruits1.Except(fruits2);
foreach (var fruit in fruits)
{
WriteLine(fruit);
}
Code language: C# (cs)
Output:
Apple
Orange
Code language: C# (cs)
3) Using LINQ Except() method with a list of objects
Suppose you have a Person
class with properties SSN
and Name
:
public class Person
{
public required string SSN
{
get; set;
}
public required string Name
{
get; set;
}
public override string ToString() => $"{Name}<{SSN}>";
}
Code language: C# (cs)
The following example uses the Except()
method to find the potential candidates who are in the candidate list but not in the Employees
list:
using static System.Console;
var candiates = new List<Person>
{
new Person() { SSN="111222333", Name="John Doe" },
new Person() { SSN="111222334", Name="Jane Doe" },
new Person() { SSN="111222335", Name="Emily Johnson" },
new Person() { SSN="111222336", Name="William Brown" },
new Person() { SSN="111222337", Name="Sarah Davis" },
};
var employees = new List<Person>
{
new Person() { SSN="111222333", Name="John Doe" },
new Person() { SSN="111222334", Name="Jane Doe" }
};
var potentialCandidates = candiates.Except(employees);
foreach (var candidate in potentialCandidates)
{
Console.WriteLine(candidate);
}
Code language: C# (cs)
Output:
John Doe <111222333>
Jane Doe <111222334>
Emily Johnson <111222335>
William Brown <111222336>
Sarah Davis <111222337>
Code language: C# (cs)
It returns all the elements in the candidate’s list. The reason is that the Except()
method compares the object by references by default.
Even though the two objects have the same properties, they are not referencing the same object. Therefore, they are not considered equal.
Suppose that two people are the same if they have the same SSN
, you can implement a customer IEqualityComparer
:
public class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person? x, Person? y)
{
// Check for null values
if (x == null || y == null)
return false;
// Check if the two Person objects are the same reference
if (ReferenceEquals(x, y))
return true;
// Compare the SSN of the two Person objects
// to determine if they're the same
return x.SSN == y.SSN;
}
public int GetHashCode(Person? obj)
{
if (obj == null || obj.SSN == null)
return 0;
// Use the SSN of the Person object
// as the hash code
return obj.SSN.GetHashCode();
}
}
Code language: C# (cs)
And pass the PersonComparer
to the Except()
method:
using static System.Console;
var candiates = new List<Person>
{
new Person() { SSN="111222333", Name="John Doe" },
new Person() { SSN="111222334", Name="Jane Doe" },
new Person() { SSN="111222335", Name="Emily Johnson" },
new Person() { SSN="111222336", Name="William Brown" },
new Person() { SSN="111222337", Name="Sarah Davis" },
};
var employees = new List<Person>
{
new Person() { SSN="111222333", Name="John Doe" },
new Person() { SSN="111222334", Name="Jane Doe" }
};
var potentialCandidates = candiates.Except(
employees,
new PersonComparer()
);
foreach (var candidate in potentialCandidates)
{
Console.WriteLine(candidate);
}
Code language: C# (cs)
Output:
Emily Johnson <111222335>
William Brown <111222336>
Sarah Davis <111222337>
Code language: C# (cs)
Summary
- Use the LINQ
Except()
method to retrieve elements from the first list that are not in the second list. - Use a custom
IEqualityComparer
to override the default equality comparer.