LINQ Exceto

Resumo : neste tutorial, você aprenderá como usar o Except()método LINQ para recuperar os elementos de uma sequência que não estão presentes em outra sequência.

Introdução ao método LINQ Except()

O método LINQ Except()permite obter os elementos da primeira sequência que não estão na segunda sequência. Ele retorna uma nova sequência com o tipo IEnumerable<T>que contém esses elementos.

Aqui está a sintaxe do Except()método LINQ:

IEnumerable<TSource> Except<TSource> (
   this IEnumerable<TSource> first, 
   IEnumerable<TSource> second
);Linguagem de código:  C#  ( cs )

O Except()método aceita dois parâmetros firste second que possuem o IEnumerable<T>tipo.

O Except()método retorna elementos firstque não aparecem no secondmas não vice-versa. Em outras palavras, ele não retorna elementos em second, mas não aparece em first. Além disso, retorna apenas elementos únicos .

Por padrão, o Except()método compara os elementos nas sequências por suas referências, se forem objetos, ou por seus valores, se forem tipos primitivos.

Para substituir o comparador de igualdade padrão, implemente um personalizado IEqualityComparer<T>e passe-o para o Except()método:

IEnumerable<TSource> Except<TSource> (
   IEnumerable<TSource> first, 
   IEnumerable<TSource> second, 
   IEqualityComparer<TSource>? comparer
);Linguagem de código:  C#  ( cs )

Nesta sintaxe, você define uma classe que implementa a IEqualityComparerinterface e a passa para o Except()método.

Exemplos de métodos LINQ Except()

Vejamos alguns exemplos de uso do Except()método LINQ.

1) Usando o método LINQ Except() com uma lista de inteiros

O exemplo a seguir usa o Except()método para retornar os números da primeira lista que não estão presentes na segunda lista:

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);
}Linguagem de código:  C#  ( cs )

Saída:

3
4Linguagem de código:  C#  ( cs )

2) Usando o método LINQ Except() com uma lista de strings

O exemplo a seguir usa o Except()método para retornar elementos da primeira lista, mas não estão na segunda lista:

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);
}Linguagem de código:  C#  ( cs )

Saída:

Apple
OrangeLinguagem de código:  C#  ( cs )

3) Usando o método LINQ Except() com uma lista de objetos

Suponha que você tenha uma Personclasse com propriedades SSNe Name:

public class Person
{
    public required string SSN
    {
        get; set;
    }
    public required string Name
    {
        get; set;
    }

    public override string ToString() => $"{Name}<{SSN}>";
}Linguagem de código:  C#  ( cs )

O exemplo a seguir usa o Except()método para localizar os candidatos potenciais que estão na lista de candidatos, mas não na Employeeslista:

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);
}Linguagem de código:  C#  ( cs )

Saída:

John Doe <111222333>
Jane Doe <111222334>
Emily Johnson <111222335>
William Brown <111222336>
Sarah Davis <111222337>Linguagem de código:  C#  ( cs )

Retorna todos os elementos da lista do candidato. A razão é que o Except()método compara o objeto por referências por padrão.

Embora os dois objetos tenham as mesmas propriedades, eles não fazem referência ao mesmo objeto. Portanto, eles não são considerados iguais.

Suponha que duas pessoas sejam iguais, se tiverem o mesmo SSN, você pode implementar um cliente 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();
    }
}Linguagem de código:  C#  ( cs )

E passe PersonComparerpara o Except()método:

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);
}Linguagem de código:  C#  ( cs )

Saída:

Emily Johnson <111222335>
William Brown <111222336>
Sarah Davis <111222337>Linguagem de código:  C#  ( cs )

Resumo

  • Use o método LINQ Except()para recuperar elementos da primeira lista que não estão na segunda lista.
  • Use um personalizado IEqualityComparerpara substituir o comparador de igualdade padrão.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *