2011-04-08 14 views
18

Dada una clase con la siguiente definición:mediante LINQ para encontrar duplicados a través de múltiples propiedades

public class MyTestClass 
{ 
    public int ValueA { get; set; } 
    public int ValueB { get; set; } 
} 

¿Cómo se pueden encontrar valores duplicados en una matriz MyTestClass []?

Por ejemplo,

MyTestClass[] items = new MyTestClass[3]; 
items[0] = new MyTestClass { ValueA = 1, ValueB = 1 }; 
items[1] = new MyTestClass { ValueA = 0, ValueB = 1 }; 
items[2] = new MyTestClass { ValueA = 1, ValueB = 1 }; 

contiene un duplicado, ya que hay dos objetos MyTestClass donde ValorA y ValorB tanto = 1

Respuesta

39

Usted puede encontrar sus duplicados por agrupar los elementos por ValorA y ValorB. Cuente con ellos luego y encontrará cuáles son duplicados.

Así es como se aislaría a los incautos:

var duplicates = items.GroupBy(i => new {i.ValueA, i.ValueB}) 
    .Where(g => g.Count() > 1) 
    .Select(g => g.Key); 
+2

Exactamente lo que estaba buscando! Usted gana un internet. Muchas gracias. –

1

MyTestClass deberían aplicar el método Equals.

public bool Equals(MyTestClass x, MyTestClass y) 
{ 
    if (Object.ReferenceEquals(x, y)) return true; 

    if (Object.ReferenceEquals(x, null) || 
     Object.ReferenceEquals(y, null)) 
      return false; 

     return x.ValueA == y.ValueA && y.ValueB == y.ValueB; 
} 

Aquí tienes un total de good article.

Después de eso, puede obtener una lista "limpia" de MyTestClass con el método "Distinct".

+2

Si Distinct va a funcionar, tendrá que hacer más que implementar el método Equals. Debe implementar la interfaz IEquatable y asegurarse de implementar GetHashCode y object equals correctamente. –

+0

Correcto, mi culpa ;-) De todos modos no es demasiado trabajo ... y puede ser interesante en muchos escenarios ;-) – zapico

3

Puede utilizar Jon Skeet's DistinctBy y Except juntos para encontrar duplicados. Vea this Response para su explicación de DistinctBy.

MyTestClass[] items = new MyTestClass[3]; 
items[0] = new MyTestClass { ValueA = 1, ValueB = 1 }; 
items[1] = new MyTestClass { ValueA = 0, ValueB = 1 }; 
items[2] = new MyTestClass { ValueA = 1, ValueB = 1 }; 

MyTestClass [] distinctItems = items.DistinctBy(p => new {p.ValueA, p.ValueB}).ToArray(); 
MyTestClass [] duplicates = items.Except(distinctItems).ToArray(); 

Sin embargo, solo devolverá un elemento y no ambos duplicados.

Cuestiones relacionadas