一尘不染

LINQ在特定属性上的Distinct()

c#

我正在与LINQ一起学习它,但是Distinct当我没有一个简单的列表(一个简单的整数列表很容易做到,这不是问题)时,我无法弄清楚该如何使用。如果要在对象的
一个多个
属性的对象列表上使用Distinct,该怎么办?


示例:如果一个对象是Person,则带有Property Id。如何获得所有Person并将Distinct其与Id对象的属性一起使用?

Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"

我怎样才能得到公正Person1Person3?那可能吗?

如果LINQ无法实现,那么Person根据.NET 3.5中的某些属性列出内容的最佳方法是什么?


阅读 276

收藏
2020-05-19

共1个答案

一尘不染

编辑 :这现在是MoreLINQ的一部分。

您需要的是有效的“与众不同”。尽管它很容易编写,但我不认为它是LINQ的一部分。

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
    (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    HashSet<TKey> seenKeys = new HashSet<TKey>();
    foreach (TSource element in source)
    {
        if (seenKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

因此,仅使用Id属性来查找不同的值,可以使用:

var query = people.DistinctBy(p => p.Id);

要使用多个属性,可以使用匿名类型,它们可以适当地实现相等性:

var query = people.DistinctBy(p => new { p.Id, p.Name });

未经测试,但它应该可以工作(现在至少可以编译)。

但是,它假定键的默认比较器-如果要传递相等比较器,只需将其传递给HashSet构造函数。

2020-05-19