2010-01-17 23 views
8

Czy można uzyskać różne elementy obiektu List w oparciu o właściwość obiektów w obiekcie List?Linq Distinct na podstawie właściwości obiektu

cos takiego jak: Distinct(x => x.id)

Co nie jest przydatny dla mnie jest następujący: .Select(x => x.id).Distinct() bo wtedy bym dostać z powrotem List<int> zamiast List<MyClass>

+0

Prawie takie same jak: http://stackoverflow.com/questions/520030/why-is-there-no-linq-method-to-return-distinct-values-by-a-predicate –

Odpowiedz

2

Trzeba DistinctBy. To nie jest część standardowych bibliotek .NET, ale Jon Skeet wykonał ją dla Linqa na obiektach here. Jest również zawarty w morelinq.

6

To brzmi jak ugrupowania skonstruować do mnie, bo trzeba zdecydować, które rzekomo identyczny obiekt rzeczywiście chcesz powrócić

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

Tylko dlatego Id jest identyczna w wielu przedmiotów, nie oznacza, że elementy są identyczne w innych właściwościach, więc musisz wyraźnie zdecydować, który element jest zwracany.

5

Co można zrobić, to zaimplementować własną IEqualityComparer<T> i przekazać, że do 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(); 
    } 
} 

Następnie:

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

Jest przeciążenie Enumerable.Distinct() że trwa IEqualityComparer.

Oto przykład, gdzie użyłem go do filtrowania liczby całkowite od parytetu:

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); 
    } 

Jest niezdarny; DistinctBy będzie czystszy.

Powiązane problemy