Qual é o mais rápido (e menos intensivo em recursos) para comparar dois itens massivos (> 50.000) e, como resultado, possui duas listas como as abaixo:
- itens que aparecem na primeira lista, mas não na segunda
- itens que aparecem na segunda lista, mas não na primeira
Atualmente, estou trabalhando com a List ou IReadOnlyCollection e resolvo esse problema em uma consulta linq:
var list1 = list.Where(i => !list2.Contains(i)).ToList();
var list2 = list2.Where(i => !list.Contains(i)).ToList();
Mas isso não funciona tão bem quanto eu gostaria. Alguma idéia de tornar esse recurso mais rápido e menos intensivo, pois preciso processar muitas listas?
Equals(object)
e / ou implementa,IEquatable<T>
ele deve estar bem.IEquatable<T>
implementação ou oobject.Equals(object)
método. Parece que você deve criar uma nova pergunta com um exemplo reproduzível mínimo - não podemos realmente diagnosticar coisas nos comentários.Mais eficiente seria usar
Enumerable.Except
:Este método é implementado usando a execução adiada. Isso significa que você pode escrever por exemplo:
Também é eficiente, pois usa internamente a
Set<T>
para comparar os objetos. Ele funciona coletando primeiro todos os valores distintos da segunda sequência e depois transmitindo os resultados da primeira, verificando se eles não foram vistos antes.fonte
Set<T>
é construído a partir da segunda sequência (ou seja, é totalmente iterado e armazenado), e então os itens que podem ser adicionados a partir da primeira sequência são gerados.Where
é parcialmente adiada porque nolist.Where(x => x.Id == 5)
valor do número5
é armazenado no início, em vez de ser executado preguiçosamente.Isso funciona para todos os tipos de dados primitivos. Se você precisar usá-lo em objetos personalizados, precisará implementar
IEqualityComparer
Define métodos para suportar a comparação de objetos para igualdade.
fonte
SequenceEqual
é simplesbool
. O OP deseja duas listas de resultados - e descreve o que deseja em termos de operações definidas: "itens que aparecem na primeira lista, mas não na segunda". Não há indicação de que o pedido seja relevante, enquanto o SequenceEqual o considera relevante. Isso parece estar respondendo a uma pergunta totalmente diferente.Se você deseja que os resultados não diferenciam maiúsculas de minúsculas , o seguinte funcionará:
firstNotSecond
conteria b1.dllsecondNotFirst
conteria b2.dllfonte
Não é para esse problema, mas aqui está um código para comparar listas iguais e não! objetos idênticos:
fonte
Except
tente desta maneira:
fonte
Às vezes, você só precisa saber se duas listas são diferentes, e não quais são essas diferenças. Nesse caso, considere adicionar esse método de extensão ao seu projeto. Observe que seus objetos listados devem implementar o IEquatable!
Uso:
Qualquer que seja a
Component
classe, os métodos mostrados aquiCar
devem ser implementados quase de forma idêntica.É muito importante observar como escrevemos GetHashCode. Para implementar corretamente
IEquatable
,Equals
eGetHashCode
deve operar nas propriedades da instância de uma maneira logicamente compatível.Duas listas com o mesmo conteúdo ainda são objetos diferentes e produzirão códigos de hash diferentes. Como queremos que essas duas listas sejam tratadas como iguais, devemos
GetHashCode
produzir o mesmo valor para cada uma delas. Podemos fazer isso delegando o código de hash a todos os elementos da lista e usando o XOR bit a bit padrão para combiná-los todos. O XOR é independente de ordem, portanto, não importa se as listas são classificadas de maneira diferente. É importante apenas que eles contenham apenas membros equivalentes.Nota: o nome estranho é implicar o fato de que o método não considera a ordem dos elementos na lista. Se você se importa com a ordem dos elementos na lista, esse método não é para você!
fonte
Eu usei esse código para comparar duas listas com milhões de registros.
Este método não levará muito tempo
fonte
Se apenas um resultado combinado for necessário, isso também funcionará:
onde T é o tipo de elemento de listas.
fonte
Pode ser engraçado, mas funciona para mim
string.Join ("", List1)! = string.Join ("", List2)
fonte
Eu acho que essa é uma maneira simples e fácil de comparar duas listas elemento por elemento
fonte
Esta é a melhor solução que você encontrará
fonte
List<T>
para cada elementolist1
. Além disso, o resultado é chamadolist3
quando não é umList<T>
.