2010-07-13 28 views
7

Tengo una clase simple que representa un objeto. Tiene 5 propiedades (una fecha, 2 decimales, un entero y una cadena). Tengo una clase de colección, derivada de CollectionBase, que es una clase contenedor para contener varios objetos de mi primera clase.¿Cómo encontrar y eliminar objetos duplicados en una colección usando LINQ?

Mi pregunta es, quiero eliminar objetos duplicados (por ejemplo, objetos que tienen la misma fecha, los mismos decimales, los mismos números enteros y la misma cadena). ¿Hay alguna consulta LINQ que pueda escribir para buscar y eliminar duplicados? ¿O encontrarlos como mínimo?

Respuesta

10

Puede eliminar duplicados con el operador Distinct.

Existen dos sobrecargas: una utiliza el comparador de igualdad predeterminado para su tipo (que para un tipo personalizado llamará al método Equals() en el tipo). El segundo le permite suministrar su propio comparador de igualdad. Ambos devuelven una nueva secuencia que representa su conjunto original sin duplicados. Ni la sobrecarga realmente modifica su colección inicial; ambos devuelven una nueva secuencia que excluye los duplicados..

Si desea simplemente encontrar los duplicados, puede utilizar GroupBy para hacerlo:

var groupsWithDups = list.GroupBy(x => new { A = x.A, B = x.B, ... }, x => x) 
         .Where(g => g.Count() > 1); 

Para eliminar los duplicados de algo así como un IList<> que podría hacer:

yourList.RemoveAll(yourList.Except(yourList.Distinct())); 
+0

¿Esto los eliminará de mi colección o solo de la consulta LINQ? – Icemanind

+0

Los métodos de extensión LINQ crean nuevos conjuntos de elementos, su colección original permanecerá intacta. –

+0

¡Gracias por toda la información! – Icemanind

4

Si su sencilla clase utiliza Equals de manera que satisfaga sus requisitos, entonces puede usar el método Distinto

var col = ...; 
var noDupes = col.Distinct(); 

Si no es así, deberá proporcionar una instancia de IEqualityComparer<T> que compare los valores de la manera que desee. Por ejemplo (nulos problemas ignorados por razones de brevedad)

public class MyTypeComparer : IEqualityComparer<MyType> { 
    public bool Equals(MyType left, MyType right) { 
    return left.Name == right.Name; 
    } 
    public int GetHashCode(MyType type) { 
    return 42; 
    } 
} 

var noDupes = col.Distinct(new MyTypeComparer()); 

Observe el uso de una constante para GetHashCode es intencional. Sin conocer los detalles íntimos sobre la semántica de MyType es imposible escribir una función de hash eficiente y correcta. En lugar de una función hash eficiente, utilicé una constante que es correcta independientemente de la semántica del tipo.

+0

¿Esto los eliminará de mi colección? ¿O solo la consulta LINQ? – Icemanind

+0

@icemanind devolverá una nueva colección que no tiene duplicados. No modificará una colección en su lugar. – JaredPar

+1

respuesta excelente y mejor práctica – danielea

Cuestiones relacionadas