2010-01-17 106 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会更干净。