Alguém tem um método rápido para desduplicar uma lista genérica em c #?
c#
list
generics
duplicates
JC Grubbs
fonte
fonte
ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);
Respostas:
Talvez você deva considerar o uso de um HashSet .
No link MSDN:
fonte
HashSet
não possui um índice , portanto, nem sempre é possível usá-lo. Eu tenho que criar uma vez uma lista enorme sem duplicatas e usá-loListView
no modo virtual. Foi super rápido fazer oHashSet<>
primeiro e depois convertê-lo em umList<>
(assim éListView
possível acessar itens por índice).List<>.Contains()
é muito lento.Se você estiver usando o .Net 3+, poderá usar o Linq.
fonte
E se:
No .net 3.5?
fonte
Basta inicializar um HashSet com uma lista do mesmo tipo:
Ou, se você deseja que uma lista seja retornada:
fonte
List<T>
usar como resultadonew HashSet<T>(withDupes).ToList()
Classifique-o e marque dois e dois ao lado do outro, pois as duplicatas se agruparão.
Algo assim:
Notas:
fonte
RemoveAt
é uma operação muito cara em umList
Eu gosto de usar este comando:
Eu tenho esses campos na minha lista: Id, StoreName, City, PostalCode Eu queria mostrar a lista de cidades em um menu suspenso que possui valores duplicados. solução: agrupe por cidade e escolha o primeiro da lista.
Espero que ajude :)
fonte
Funcionou para mim. simplesmente use
Substitua "Type" pelo tipo desejado, por exemplo, int.
fonte
Como o kronoz disse no .Net 3.5, você pode usar
Distinct()
.No .Net 2 você pode imitá-lo:
Isso pode ser usado para desduplicar qualquer coleção e retornará os valores na ordem original.
Normalmente, é muito mais rápido filtrar uma coleção (como ambos
Distinct()
e esta amostra) do que seria remover itens dela.fonte
HashSet
construtor foi deduplicado, o que o torna melhor para a maioria das circunstâncias. No entanto, isso preservaria a ordem de classificação, queHashSet
não é.Dictionary<T, object>
vez, substituir.Contains
com.ContainsKey
e.Add(item)
com.Add(item, null)
HashSet
preserva a ordem, enquantoDistinct()
não.Um método de extensão pode ser uma maneira decente de seguir ... algo como isto:
E então chame assim, por exemplo:
fonte
Em Java (presumo que o C # seja mais ou menos idêntico):
Se você realmente deseja alterar a lista original:
Para preservar a ordem, basta substituir o HashSet por LinkedHashSet.
fonte
var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes);
:)Isso leva distintos (os elementos sem duplicar elementos) e converte-os em uma lista novamente:
fonte
Nota: Esta solução não requer conhecimento do Linq, além do que existe.
Código
Comece adicionando o seguinte ao topo do seu arquivo de turma:
Agora, você pode usar o seguinte para remover duplicatas de um objeto chamado
obj1
:Nota: Renomeie
obj1
para o nome do seu objeto.Como funciona
O comando União lista uma de cada entrada de dois objetos de origem. Como obj1 são os dois objetos de origem, isso reduz o obj1 a uma de cada entrada.
O
ToList()
retorna uma nova lista. Isso é necessário, porque os comandos do LinqUnion
retornam o resultado como um resultado IEnumerable em vez de modificar a lista original ou retornar uma nova lista.fonte
Como método auxiliar (sem Linq):
fonte
Se você não se preocupam com a ordem que você pode apenas empurrar os itens em um
HashSet
, se você não quiser manter a ordem que você pode fazer algo como isto:Ou a maneira Linq:
Edit: O
HashSet
método éO(N)
tempo eO(N)
espaço ao classificar e, em seguida, tornar único (como sugerido por @ lassevk e outros) éO(N*lgN)
tempo eO(1)
espaço, então não está tão claro para mim (como era à primeira vista) que a forma de classificação é inferior (minha desculpas pelo voto temporário encerrado ...)fonte
Aqui está um método de extensão para remover duplicatas adjacentes in situ. Chame Sort () primeiro e passe no mesmo IComparer. Isso deve ser mais eficiente que a versão de Lasse V. Karlsen, que chama RemoveAt repetidamente (resultando em vários movimentos da memória do bloco).
fonte
Instalando o pacote MoreLINQ via Nuget, você pode facilmente distinguir a lista de objetos por uma propriedade
fonte
Pode ser mais fácil simplesmente garantir que duplicatas não sejam adicionadas à lista.
fonte
List<T>.Contains
método todas as vezes, mas com mais de 1.000.000 de entradas. Esse processo atrasa meu aplicativo. Estou usando umaList<T>.Distinct().ToList<T>()
primeira vez.Você pode usar o Union
fonte
Outra maneira no .Net 2.0
fonte
Há muitas maneiras de resolver - a questão das duplicatas na lista, abaixo é uma delas:
Felicidades Ravi Ganesan
fonte
Aqui está uma solução simples que não requer nenhum LINQ difícil de ler ou qualquer classificação prévia da lista.
fonte
A resposta de David J. é um bom método, sem necessidade de objetos extras, classificação, etc. No entanto, pode ser aprimorado:
for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)
Portanto, o loop externo fica no topo da parte inferior da lista inteira, mas o loop interno fica no fundo "até que a posição do loop externo seja atingida".
O loop externo assegura que toda a lista seja processada, o loop interno encontra as duplicatas reais, elas só podem acontecer na parte que o loop externo ainda não processou.
Ou, se você não quiser fazer de baixo para cima para o loop interno, poderá iniciar o loop interno em outerIndex + 1.
fonte
Todas as respostas copiam listas, ou criam uma nova lista, ou usam funções lentas, ou são extremamente lentas.
Na minha opinião, esse é o método mais rápido e mais barato que conheço (também apoiado por um programador muito experiente, especializado em otimização física em tempo real).
O custo final é:
nlogn + n + nlogn = n + 2nlogn = O (nlogn), o que é bastante agradável.
Nota sobre o RemoveRange: Como não podemos definir a contagem da lista e evitar o uso das funções Remover, não sei exatamente a velocidade dessa operação, mas acho que é a maneira mais rápida.
fonte
Se você tem aulas de reboque
Product
eCustomer
queremos remover itens duplicados da listaVocê deve definir uma classe genérica no formulário abaixo
Você pode remover itens duplicados da sua lista.
esse código remove itens duplicados por
Id
se você deseja remover itens duplicados por outra propriedade, você pode alterar onameof(YourClass.DuplicateProperty)
mesmonameof(Customer.CustomerName)
e remover itens duplicados porCustomerName
Propriedade.fonte
fonte
Uma implementação intuitiva simples:
fonte