2010-01-17 103 views
8

是否有可能基於List中對象的屬性獲取List的不同元素?Linq基於對象屬性的不同

成才這樣的:Distinct(x => x.id)

有什麼理由不有用,我是以下幾點:.Select(x => x.id).Distinct(),因爲那時我還是會回到一個List<int>,而不是List<MyClass>

+0

差不多相同:http://stackoverflow.com/questions/520030/why-is-there-no-linq-method-to-return-distinct-values-by-a-predicate – 2010-01-17 20:58:45

回答

2

你需要DistinctBy。它不是標準.NET庫的一部分,但是Jon Skeet爲Linq實現了對象here。它也包含在morelinq中。

6

這聽起來像一個分組構建我的,因爲你需要決定哪些理應相同對象的你真的想回到

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

只是因爲ID在多個項目相同並不意味着項目在其他屬性上是相同的,所以您需要明確地決定返回哪個項目。

5

你可以做的是實現自己的IEqualityComparer<T>並傳遞到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(); 
    } 
} 

然後:

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

上有Enumerable.Distinct()這需要IEqualityComparer過載。

在此處,我用它通過奇偶校驗來過濾整數的例子:

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

這是笨拙; DistinctBy會更乾淨。