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 first
e second
que possuem o IEnumerable<T>
tipo.
O Except()
método retorna elementos first
que não aparecem no second
mas 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 IEqualityComparer
interface 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
4
Linguagem 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
Orange
Linguagem de código: C# ( cs )
3) Usando o método LINQ Except() com uma lista de objetos
Suponha que você tenha uma Person
classe com propriedades SSN
e 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 Employees
lista:
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 PersonComparer
para 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
IEqualityComparer
para substituir o comparador de igualdade padrão.