LINQ ExceptBy

Summary: in this tutorial, you will learn how to use the LINQ ExceptBy() method to find the set difference between two sequences by a key selector function.

Introduction to the LINQ ExceptBy() method

The ExceptBy() method returns unique elements of the first sequence that don’t appear in the second sequence by a key selector function.

Here’s the syntax of the ExceptBy() method:

IEnumerable<TSource> ExceptBy<TSource> (
    this IEnumerable<TSource> first, 
    IEnumerable<TKey> second,
    Func<TSource,TKey> keySelector
);Code language: C# (cs)

In this syntax:

  • TSource is the type of element of the input sequence.
  • TKey is the type of key that the method uses to identify the elements.
  • first is an IEnumerable<TSource> whose keys that are not in the second will be included in the result.
  • second is an IEnumable<TKey> whose keys that occur in the first sequence will cause those elements to be excluded from the result.
  • keySelector is a function that extracts the key for each element.

The ExceptBy() method returns an IEnumerable<TSource> that contains the set difference of elements of the first and second sequences.

LINQ ExceptBy() method examples

Let’s take some examples of using the LINQ ExceptBy() method.

1) Using the LINQ ExceptBy to find the set differences between two sequences of objects

Suppose you have the following Person class with two 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 ExceptBy() method to return candidates that are not employees by comparing the SSN of the candidates with employees:

using static System.Console;

var candidates = new List<Person>
{
    new Person() { SSN="1234567890", Name="John Doe" },
    new Person() { SSN="1234567891", Name="Jane Doe" },
    new Person() { SSN="1234567892", Name="Emily Johnson" },
    new Person() { SSN="1234567893", Name="William Brown" },
    new Person() { SSN="1234567894", Name="Sarah Davis" },
};

var employees = new List<Person>
{
    new Person() { SSN="1234567890", Name="John Doe" },
    new Person() { SSN="1234567891", Name="Jane Doe" }
};


var potentialCandidates = candidates.ExceptBy(
        employees.Select(e => e.SSN),
        e => e.SSN
);

foreach (var candidate in potentialCandidates)
{
    WriteLine(candidate);
}Code language: C# (cs)

Output:

Emily Johnson <1234567892>
William Brown <1234567893>
Sarah Davis <1234567894>Code language: plaintext (plaintext)

In the following code:

var potentialCandidates = candidates.ExceptBy(
        employees.Select(e => e.SSN),
        e => e.SSN
);Code language: C# (cs)

How it works.

  • TSource is the Person class and TKey is the SSN property of the Person class.
  • candidates list is the IEnumerable<TSource>
  • employees.Select(e => e.SSN) returns an IEnumerable<TKey> that contains a sequence of SSNs of employees.
  • e => e.SSN is the key selector function that returns the SSN key for comparing Person objects in the candidate and employee lists.

2) Using the LINQ ExceptBy method to find the set differences between two sequences of different object shapes

The following example uses the ExceptBy() method to find all employees except the ones that have a salary of 100,000 or 120,000:

using static System.Console;

public record Employee(string Name, decimal Salary);

public class Program
{
    public static void Main(string[] args)
    {
        var employees = new List<Employee>()
        {
            new Employee("John Doe", 120_000),
            new Employee("John Doe", 100_000),
            new Employee("Sarah Davis", 100_000),
            new Employee("Emily Johnson", 150_000),
            new Employee("Alice Miller", 130_000)
        };

        var salaries = new decimal[] { 120_000, 100_000 };

        var results = employees.ExceptBy(salaries, e => e.Salary);

        foreach (var employee in results)
        {
            WriteLine(employee);
        }
    }
}Code language: C# (cs)

Output:

Employee { Name = Emily Johnson, Salary = 150000 }
Employee { Name = Alice Miller, Salary = 130000 }Code language: plaintext (plaintext)

Summary

  • Use the LINQ ExceptBy() method to retrieve the elements in the first sequence that do not appear in the second sequence by comparing the elements by a key selector function.
Was this tutorial helpful ?