LINQ在特定属性上的Distinct()

我正在玩LINQ来了解它,但是当我没有一个简单的列表(一个简单的整数列表很容易做,这不是问题)时,我无法弄清楚如何使用Distinct。 我如果想在对象的一个​​或多个属性上使用Distinct?

例如:如果一个对象是Person ,并带有Property Id 。 我如何获得所有人并使用对象的属性Id对他们使用Distinct

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

我怎样才能得到Person1和Person3? 那可能吗?

如果这是不可能的使用LINQ,这将是有名单的最好办法Person依赖于它的一些属性在.NET 3.5?


编辑 :这现在是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构造器。


如果我想根据一个或多个属性获取不同的列表,该怎么办?

简单! 你想分组他们并从组中选出一个优胜者。

List<Person> distinctPeople = allPeople
  .GroupBy(p => p.PersonId)
  .Select(g => g.First())
  .ToList();

如果您想要定义多个属性上的组,请按照下列步骤操作:

List<Person> distinctPeople = allPeople
  .GroupBy(p => new {p.PersonId, p.FavoriteColor} )
  .Select(g => g.First())
  .ToList();

你也可以使用查询语法,如果你想让它看起来像所有LINQ一样:

var uniquePeople = from p in people
                   group p by new {p.ID} //or group by new {p.ID, p.Name, p.Whatever}
                   into mygroup
                   select mygroup.FirstOrDefault();
链接地址: http://www.djcxy.com/p/1457.html

上一篇: LINQ's Distinct() on a particular property

下一篇: What is the difference between a 'closure' and a 'lambda'?