我玩LINQ来了解它,但我不知道如何使用鲜明当我没有一个简单的列表(一个简单的整数列表是很容易做到的,这不是问题)。如果我想使用鲜明的列表<TElement>上的一个或多个属性的TElement?

示例:如果一个对象是Person,具有属性Id。我怎么能得到所有人,并使用鲜明对他们与对象的属性Id ?

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

如何得到Person1和Person3?这可能吗?

如果用LINQ是不可能的,那么根据Person的某些属性获得Person列表的最佳方法是什么?


当前回答

也许这个能帮上忙,试试这个。使用HashSet可以提高代码性能。

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    var known = new HashSet<TKey>();
    return source.Where(element => known.Add(keySelector(element)));
}

其他回答

List<Person>lst=new List<Person>
        var result1 = lst.OrderByDescending(a => a.ID).Select(a =>new Player {ID=a.ID,Name=a.Name} ).Distinct();

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

也许这个能帮上忙,试试这个。使用HashSet可以提高代码性能。

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    var known = new HashSet<TKey>();
    return source.Where(element => known.Add(keySelector(element)));
}

下面的代码在功能上等同于Jon Skeet的答案。

在. net 4.5上测试,应该可以在任何早期版本的LINQ上运行。

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

顺便说一句,请在谷歌Code上查看Jon Skeet的最新版本的DistinctBy.cs。

更新2022-04-03

根据Andrew McClement的评论,最好接受John Skeet的回答。

你应该能够覆盖Equals on person来实际执行Equals on person。id。这应该会导致你所追求的行为。