2010-01-17 11 views
8

¿Es posible obtener los distintos elementos de un List según una propiedad de los objetos en el List?Linq Distinto basado en la propiedad del objeto

calle detrás como: Distinct(x => x.id)

Lo que no es muy útil para mí es el siguiente: .Select(x => x.id).Distinct() porque entonces me gustaría volver a un lugar de List<int>List<MyClass>

+0

Casi lo mismo que: http://stackoverflow.com/questions/520030/why-is-there-no-linq-method-to-return-distinct-values-by-a-predicate –

Respuesta

2

Necesitas DistinctBy. No forma parte de las bibliotecas .NET estándar, pero Jon Skeet realizó una implementación de Linq para los objetos here. También está incluido en morelinq.

6

Eso suena como una agrupación construir para mí, porque hay que decidir cual de los objetos supuestamente idéntica en realidad se desea volver

var q = from x in foo 
     group x by x.Id into g 
     select g.First(); // or some other selection from g 

El hecho de que Id es idéntico a través de varios elementos, no significa que el los elementos son idénticos en otras propiedades, por lo que debe decidir explícitamente qué artículo se devuelve.

5

Lo que puede hacer es poner en práctica su propio IEqualityComparer<T> y pasar a que Distinct:

class SomeType { 
    public int id { get; set; } 
    // other properties 
} 
class EqualityComparer : IEqualityComparer<SomeType> { 
    public bool Equals(SomeType x, SomeType y) { 
     return x.id == y.id; 
    } 

    public int GetHashCode(SomeType obj) { 
     return obj.id.GetHashCode(); 
    } 
} 

continuación:

// elements is IEnumerable<SomeType> 
var distinct = elements.Distinct(new EqualityComparer()); 
// distinct is IEnumerable<SomeType> and contains distinct items from elements 
// as per EqualityComparer 
2

Hay una sobrecarga en Enumerable.Distinct() que toma IEqualityComparer.

He aquí un ejemplo en el que he usado para filtrar enteros por la paridad:

class IntParitiyComparer : IEqualityComparer<int> 
    { 
     public bool Equals(int x, int y) 
     { 
      return x % 2 == y % 2; 
     } 

     public int GetHashCode(int obj) 
     { 
      return obj % 2; 
     } 
    } 

    static void Main(string[] args) 
    { 
     var x = new int[] { 1, 2, 3, 4 }.Distinct(new IntParitiyComparer()); 

     foreach (var y in x) Console.WriteLine(y); 
    } 

Es torpe; DistinctBy sería más limpio.

Cuestiones relacionadas