是否可以基于List
中对象的属性获取不同的元素?
类似这样:Distinct(x => x.id)
对我没有用的是以下内容:.Select(x => x.id).Distinct()
,因为那样我会得到一个List<int>
而不是List<MyClass>
。
这听起来像是一种分组结构,因为你需要决定你想要返回哪个看似相同的对象
var q = from x in foo
group x by x.Id into g
select g.First(); // or some other selection from g
虽然多个项的Id相同,但并不意味着这些项在其他属性上也相同,因此您需要明确决定返回哪个项。
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
有一个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
会更加简洁。