¿Alguien tiene un método rápido para desduplicar una Lista genérica en C #?
c#
list
generics
duplicates
JC Grubbs
fuente
fuente
ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);
Respuestas:
Quizás debería considerar usar un HashSet .
Desde el enlace de MSDN:
fuente
HashSet
no tiene un índice , por lo tanto, no siempre es posible usarlo. Tengo que crear una vez una gran lista sin duplicados y luego usarlaListView
en modo virtual. Fue súper rápido hacer unHashSet<>
primero y luego convertirlo en unList<>
(para queListView
pueda acceder a los elementos por índice).List<>.Contains()
es muy lentoSi está usando .Net 3+, puede usar Linq.
fuente
Qué tal si:
¿En .net 3.5?
fuente
Simplemente inicialice un HashSet con una Lista del mismo tipo:
O, si desea que se devuelva una Lista:
fuente
List<T>
resultado como usonew HashSet<T>(withDupes).ToList()
Ordénelo, luego marque dos y dos uno al lado del otro, ya que los duplicados se agruparán.
Algo como esto:
Notas:
fuente
RemoveAt
es una operación muy costosa en unList
Me gusta usar este comando:
Tengo estos campos en mi lista: Id, StoreName, Ciudad, Código postal. Quería mostrar la lista de ciudades en un menú desplegable que tiene valores duplicados. solución: Agrupar por ciudad y luego elegir el primero para la lista.
Espero que ayude :)
fuente
Funcionó para mi. simplemente use
Reemplace "Tipo" con su tipo deseado, por ejemplo, int.
fuente
Como dijo kronoz en .Net 3.5, puede usarlo
Distinct()
.En .Net 2 puedes imitarlo:
Esto podría usarse para deducir cualquier colección y devolverá los valores en el orden original.
Normalmente es mucho más rápido filtrar una colección (como ambos
Distinct()
y esta muestra) que eliminar elementos de ella.fuente
HashSet
constructor dedujo, lo que lo hace mejor para la mayoría de las circunstancias. Sin embargo, esto preservaría el orden de clasificación, queHashSet
no lo hace.Dictionary<T, object>
lugar, reemplazar.Contains
con.ContainsKey
y.Add(item)
con.Add(item, null)
HashSet
conserva el orden mientrasDistinct()
que no.Un método de extensión podría ser un camino decente ... algo como esto:
Y luego llame así, por ejemplo:
fuente
En Java (supongo que C # es más o menos idéntico):
Si realmente quería mutar la lista original:
Para preservar el orden, simplemente reemplace HashSet con LinkedHashSet.
fuente
var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes);
:)Esto toma distintos (los elementos sin elementos duplicados) y los convierte nuevamente en una lista:
fuente
Nota: Esta solución no requiere conocimiento de Linq, aparte de que existe.
Código
Comience agregando lo siguiente a la parte superior de su archivo de clase:
Ahora, puede usar lo siguiente para eliminar duplicados de un objeto llamado
obj1
:Nota: Cambie
obj1
el nombre al nombre de su objeto.Cómo funciona
El comando Unión enumera una de cada entrada de dos objetos de origen. Como obj1 es ambos objetos fuente, esto reduce obj1 a una de cada entrada.
El
ToList()
devuelve una nueva lista. Esto es necesario, porque los comandos de Linq comoUnion
devuelven el resultado como un resultado IEnumerable en lugar de modificar la Lista original o devolver una nueva Lista.fuente
Como método auxiliar (sin Linq):
fuente
Si no se preocupan por el orden que sólo puede empujar los objetos en una
HashSet
, si no desea mantener el orden en el que puede hacer algo como esto:O la forma de Linq:
Editar: El
HashSet
método esO(N)
tiempo yO(N)
espacio mientras se ordena y luego se hace único (como lo sugirieron @ lassevk y otros) esO(N*lgN)
tiempo yO(1)
espacio, por lo que no es tan claro para mí (como lo fue a primera vista) que la forma de clasificación es inferior (mi disculpas por el voto negativo temporal ...)fuente
Aquí hay un método de extensión para eliminar duplicados adyacentes in situ. Llame primero a Sort () y pase en el mismo IComparer. Esto debería ser más eficiente que la versión de Lasse V. Karlsen que llama a RemoveAt repetidamente (lo que resulta en múltiples movimientos de memoria de bloque).
fuente
Al instalar el paquete MoreLINQ a través de Nuget, puede distinguir fácilmente la lista de objetos por una propiedad
fuente
Puede ser más fácil simplemente asegurarse de que no se agreguen duplicados a la lista.
fuente
List<T>.Contains
método cada vez pero con más de 1,000,000 de entradas. Este proceso ralentiza mi solicitud. Estoy usando unList<T>.Distinct().ToList<T>()
primero en su lugar.Puedes usar Union
fuente
Otra forma en .Net 2.0
fuente
Hay muchas formas de resolver: el problema de los duplicados en la Lista, a continuación, es uno de ellos:
Saludos Ravi Ganesan
fuente
Aquí hay una solución simple que no requiere ningún LINQ difícil de leer ni ninguna clasificación previa de la lista.
fuente
La respuesta de David J. es un buen método, sin necesidad de objetos adicionales, clasificación, etc. Sin embargo, se puede mejorar:
for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)
Por lo tanto, el bucle externo va en la parte superior inferior de toda la lista, pero el bucle interno va en la parte inferior "hasta que se alcanza la posición del bucle externo".
El bucle externo se asegura de que se procese toda la lista, el bucle interno encuentra los duplicados reales, eso solo puede suceder en la parte que el bucle externo aún no ha procesado.
O si no desea hacer una búsqueda ascendente del bucle interno, puede hacer que el bucle interno comience en externalIndex + 1.
fuente
Todas las respuestas copian listas, o crean una nueva lista, o usan funciones lentas, o son dolorosamente lentas.
Según tengo entendido, este es el método más rápido y económico que conozco (también, respaldado por un programador muy experimentado especializado en la optimización física en tiempo real).
El costo final es:
nlogn + n + nlogn = n + 2nlogn = O (nlogn) lo cual es bastante bueno.
Nota sobre RemoveRange: Dado que no podemos establecer el recuento de la lista y evitar el uso de las funciones Remove, no sé exactamente la velocidad de esta operación, pero supongo que es la forma más rápida.
fuente
Si tiene clases de remolque
Product
yCustomer
queremos eliminar elementos duplicados de su listaDebe definir una clase genérica en el siguiente formulario
luego, puede eliminar elementos duplicados de su lista.
este código quitar elementos duplicados por
Id
si desea eliminar elementos duplicados por otros bienes, que puede cambiarnameof(YourClass.DuplicateProperty)
mismanameof(Customer.CustomerName)
a continuación, eliminar elementos duplicados deCustomerName
la propiedad.fuente
fuente
Una implementación intuitiva simple:
fuente