LINQ 对特定属性的 Distinct()

发布于 2024-07-12 11:50:03 字数 753 浏览 5 评论 0 原文

我正在使用 LINQ 来了解它,但我不知道如何使用 Distinct 当我没有一个简单的列表时(一个简单的整数列表很容易做到,这不是问题)。 如果想在 List一个更多 属性上使用 Distinct,该怎么办? >TElement?

示例:如果对象是 Person,具有属性 Id。 如何获取所有 Person 并通过对象的属性 Id 对他们使用 Distinct

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

我如何才能只获取 Person1Person3? 那可能吗?

如果 LINQ 无法实现,那么根据其某些属性获得 Person 列表的最佳方法是什么?

I am playing with LINQ to learn about it, but I can't figure out how to use Distinct when I do not have a simple list (a simple list of integers is pretty easy to do, this is not the question). What I if want to use Distinct on a List<TElement> on one or more properties of the TElement?

Example: If an object is Person, with property Id. How can I get all Person and use Distinct on them with the property Id of the object?

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

How can I get just Person1 and Person3? Is that possible?

If it's not possible with LINQ, what would be the best way to have a list of Person depending on some of its properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(23

哎呦我呸! 2024-07-19 11:50:03

如果我想获取基于一个更多属性的不同列表怎么办?

简单的! 您想将它们分组并从组中选出获胜者。

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();

注意:某些查询提供程序无法解析每个组必须至少有一个元素,并且 First 是在这种情况下调用的适当方法。 如果您发现自己正在与此类查询提供程序合作,FirstOrDefault 可能会帮助您通过查询提供程序获取查询。

注意 2:考虑 EF Core(EF Core 6 之前的版本)兼容方法的答案。 https://stackoverflow.com/a/66529949/8155

What if I want to obtain a distinct list based on one or more properties?

Simple! You want to group them and pick a winner out of the group.

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

If you want to define groups on multiple properties, here's how:

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

Note: Certain query providers are unable to resolve that each group must have at least one element, and that First is the appropriate method to call in that situation. If you find yourself working with such a query provider, FirstOrDefault may help get your query through the query provider.

Note2: Consider this answer for an EF Core (prior to EF Core 6) compatible approach. https://stackoverflow.com/a/66529949/8155

失眠症患者 2024-07-19 11:50:03

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

您需要的是有效的“distinct-by”。 我不相信它是 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 构造函数即可。

EDIT: This is now part of MoreLINQ.

What you need is a "distinct-by" effectively. I don't believe it's part of LINQ as it stands, although it's fairly easy to write:

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;
        }
    }
}

So to find the distinct values using just the Id property, you could use:

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

And to use multiple properties, you can use anonymous types, which implement equality appropriately:

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

Untested, but it should work (and it now at least compiles).

It assumes the default comparer for the keys though - if you want to pass in an equality comparer, just pass it on to the HashSet constructor.

桃扇骨 2024-07-19 11:50:03

使用:

List<Person> pList = new List<Person>();
/* Fill list */

var result = pList.Where(p => p.Name != null).GroupBy(p => p.Id)
    .Select(grp => grp.FirstOrDefault());

where 帮助您过滤条目(可能更复杂),groupbyselect 执行不同的功能。

Use:

List<Person> pList = new List<Person>();
/* Fill list */

var result = pList.Where(p => p.Name != null).GroupBy(p => p.Id)
    .Select(grp => grp.FirstOrDefault());

The where helps you filter the entries (could be more complex) and the groupby and select perform the distinct function.

迷雾森÷林ヴ 2024-07-19 11:50:03

从 .NET 6 开始,有一个使用 Linq 中新的 DistinctBy() 扩展,因此我们可以执行以下

var distinctPersonsById = personList.DistinctBy(x => x.Id);

操作: DistinctBy 方法:

// Returns distinct elements from a sequence according to a specified
// key selector function.
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector);

Starting with .NET 6, there is new solution using the new DistinctBy() extension in Linq, so we can do:

var distinctPersonsById = personList.DistinctBy(x => x.Id);

The signature of the DistinctBy method:

// Returns distinct elements from a sequence according to a specified
// key selector function.
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector);
时间你老了 2024-07-19 11:50:03

如果您希望它看起来完全像 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();

You could also use query syntax if you want it to look all LINQ-like:

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();
时光倒影 2024-07-19 11:50:03

我认为这就足够了:

list.Select(s => s.MyField).Distinct();

I think it is enough:

list.Select(s => s.MyField).Distinct();
向日葵 2024-07-19 11:50:03

解决方案首先按您的字段进行分组,然后选择 FirstOrDefault 项。

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

Solution first group by your fields then select FirstOrDefault item.

List<Person> distinctPeople = allPeople
.GroupBy(p => p.PersonId)
.Select(g => g.FirstOrDefault())
.ToList();
羁客 2024-07-19 11:50:03

您可以使用标准 Linq.ToLookup()< /a>. 这将为每个唯一键创建值的集合。 只需选择集合中的第一项

Persons.ToLookup(p => p.Id).Select(coll => coll.First());

You can do this with the standard Linq.ToLookup(). This will create a collection of values for each unique key. Just select the first item in the collection

Persons.ToLookup(p => p.Id).Select(coll => coll.First());
隱形的亼 2024-07-19 11:50:03

以下代码在功能上等同于 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)));
}

顺便说一句,请在 Google 上查看 Jon Skeet 的最新版本 DistinctBy.cs代码

更新 2022-04-03

根据 Andrew McClement 的评论,最好采用 John Skeet 的回答。

更新 2024-05-15

项目新家 MoreLINQ

The following code is functionally equivalent to Jon Skeet's answer.

Tested on .NET 4.5, should work on any earlier version of 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)));
}

Incidentially, check out Jon Skeet's latest version of DistinctBy.cs on Google Code.

Update 2022-04-03

Based on an comment by Andrew McClement, best to take John Skeet's answer over this one.

Update 2024-05-15

New home of the project MoreLINQ

回忆那么伤 2024-07-19 11:50:03

我写了一篇文章,解释如何扩展 Distinct 函数,以便您可以执行以下操作:

var people = new List<Person>();

people.Add(new Person(1, "a", "b"));
people.Add(new Person(2, "c", "d"));
people.Add(new Person(1, "a", "b"));

foreach (var person in people.Distinct(p => p.ID))
    // Do stuff with unique list here.

以下是该文章(现在位于网络存档中):扩展 LINQ - 在 Distinct 函数中指定属性< /em>

I've written an article that explains how to extend the Distinct function so that you can do as follows:

var people = new List<Person>();

people.Add(new Person(1, "a", "b"));
people.Add(new Person(2, "c", "d"));
people.Add(new Person(1, "a", "b"));

foreach (var person in people.Distinct(p => p.ID))
    // Do stuff with unique list here.

Here's the article (now in the Web Archive): Extending LINQ - Specifying a Property in the Distinct Function

九公里浅绿 2024-07-19 11:50:03

我个人使用以下类:

public class LambdaEqualityComparer<TSource, TDest> : 
    IEqualityComparer<TSource>
{
    private Func<TSource, TDest> _selector;

    public LambdaEqualityComparer(Func<TSource, TDest> selector)
    {
        _selector = selector;
    }

    public bool Equals(TSource obj, TSource other)
    {
        return _selector(obj).Equals(_selector(other));
    }

    public int GetHashCode(TSource obj)
    {
        return _selector(obj).GetHashCode();
    }
}

然后,扩展方法:

public static IEnumerable<TSource> Distinct<TSource, TCompare>(
    this IEnumerable<TSource> source, Func<TSource, TCompare> selector)
{
    return source.Distinct(new LambdaEqualityComparer<TSource, TCompare>(selector));
}

最后,预期用途:

var dates = new List<DateTime>() { /* ... */ }
var distinctYears = dates.Distinct(date => date.Year);

我发现使用此方法的优点是为接受 的其他方法重新使用 LambdaEqualityComparer 类IEqualityComparer。 (哦,我把 yield 的东西留给了原始的 LINQ 实现......)

Personally I use the following class:

public class LambdaEqualityComparer<TSource, TDest> : 
    IEqualityComparer<TSource>
{
    private Func<TSource, TDest> _selector;

    public LambdaEqualityComparer(Func<TSource, TDest> selector)
    {
        _selector = selector;
    }

    public bool Equals(TSource obj, TSource other)
    {
        return _selector(obj).Equals(_selector(other));
    }

    public int GetHashCode(TSource obj)
    {
        return _selector(obj).GetHashCode();
    }
}

Then, an extension method:

public static IEnumerable<TSource> Distinct<TSource, TCompare>(
    this IEnumerable<TSource> source, Func<TSource, TCompare> selector)
{
    return source.Distinct(new LambdaEqualityComparer<TSource, TCompare>(selector));
}

Finally, the intended usage:

var dates = new List<DateTime>() { /* ... */ }
var distinctYears = dates.Distinct(date => date.Year);

The advantage I found using this approach is the re-usage of LambdaEqualityComparer class for other methods that accept an IEqualityComparer. (Oh, and I leave the yield stuff to the original LINQ implementation...)

赢得她心 2024-07-19 11:50:03

您可以使用 DistinctBy() 通过对象属性获取不同记录。 使用前只需添加以下语句:

使用 Microsoft.Ajax.Utilities;

然后按如下方式使用它:

var listToReturn = responseList.DistinctBy(x => x.Index).ToList();

其中“索引”是我希望数据不同的属性。

You can use DistinctBy() for getting Distinct records by an object property. Just add the following statement before using it:

using Microsoft.Ajax.Utilities;

and then use it like following:

var listToReturn = responseList.DistinctBy(x => x.Index).ToList();

where 'Index' is the property on which i want the data to be distinct.

过去的过去 2024-07-19 11:50:03

您可以这样做(尽管速度不是很快):

people.Where(p => !people.Any(q => (p != q && p.Id == q.Id)));

也就是说,“选择列表中不存在具有相同 ID 的其他人的所有人员”。

请注意,在您的示例中,这只会选择第 3 个人。我不知道如何从前两个人中找出您想要的人。

You can do it (albeit not lightning-quickly) like so:

people.Where(p => !people.Any(q => (p != q && p.Id == q.Id)));

That is, "select all people where there isn't another different person in the list with the same ID."

Mind you, in your example, that would just select person 3. I'm not sure how to tell which you want, out of the previous two.

情绪失控 2024-07-19 11:50:03

如果您需要对多个属性使用不同的方法,您可以查看我的 PowerfulExtensions 库。 目前它还处于非常年轻的阶段,但您已经可以在任意数量的属性上使用 Distinct、Union、Intersect、Except 等方法;

这是你如何使用它:

using PowerfulExtensions.Linq;
...
var distinct = myArray.Distinct(x => x.A, x => x.B);

In case you need a Distinct method on multiple properties, you can check out my PowerfulExtensions library. Currently it's in a very young stage, but already you can use methods like Distinct, Union, Intersect, Except on any number of properties;

This is how you use it:

using PowerfulExtensions.Linq;
...
var distinct = myArray.Distinct(x => x.A, x => x.B);
时光倒影 2024-07-19 11:50:03

当我们在项目中面临这样的任务时,我们定义了一个小的 API 来组成比较器。

所以,用例是这样的:

var wordComparer = KeyEqualityComparer.Null<Word>().
    ThenBy(item => item.Text).
    ThenBy(item => item.LangID);
...
source.Select(...).Distinct(wordComparer);

API 本身看起来像这样:

using System;
using System.Collections;
using System.Collections.Generic;

public static class KeyEqualityComparer
{
    public static IEqualityComparer<T> Null<T>()
    {
        return null;
    }

    public static IEqualityComparer<T> EqualityComparerBy<T, K>(
        this IEnumerable<T> source,
        Func<T, K> keyFunc)
    {
        return new KeyEqualityComparer<T, K>(keyFunc);
    }

    public static KeyEqualityComparer<T, K> ThenBy<T, K>(
        this IEqualityComparer<T> equalityComparer,
        Func<T, K> keyFunc)
    {
        return new KeyEqualityComparer<T, K>(keyFunc, equalityComparer);
    }
}

public struct KeyEqualityComparer<T, K>: IEqualityComparer<T>
{
    public KeyEqualityComparer(
        Func<T, K> keyFunc,
        IEqualityComparer<T> equalityComparer = null)
    {
        KeyFunc = keyFunc;
        EqualityComparer = equalityComparer;
    }

    public bool Equals(T x, T y)
    {
        return ((EqualityComparer == null) || EqualityComparer.Equals(x, y)) &&
                EqualityComparer<K>.Default.Equals(KeyFunc(x), KeyFunc(y));
    }

    public int GetHashCode(T obj)
    {
        var hash = EqualityComparer<K>.Default.GetHashCode(KeyFunc(obj));

        if (EqualityComparer != null)
        {
            var hash2 = EqualityComparer.GetHashCode(obj);

            hash ^= (hash2 << 5) + hash2;
        }

        return hash;
    }

    public readonly Func<T, K> KeyFunc;
    public readonly IEqualityComparer<T> EqualityComparer;
}

更多详细信息请参见我们的网站:LINQ 中的 IEqualityComparer

When we faced such a task in our project we defined a small API to compose comparators.

So, the use case was like this:

var wordComparer = KeyEqualityComparer.Null<Word>().
    ThenBy(item => item.Text).
    ThenBy(item => item.LangID);
...
source.Select(...).Distinct(wordComparer);

And API itself looks like this:

using System;
using System.Collections;
using System.Collections.Generic;

public static class KeyEqualityComparer
{
    public static IEqualityComparer<T> Null<T>()
    {
        return null;
    }

    public static IEqualityComparer<T> EqualityComparerBy<T, K>(
        this IEnumerable<T> source,
        Func<T, K> keyFunc)
    {
        return new KeyEqualityComparer<T, K>(keyFunc);
    }

    public static KeyEqualityComparer<T, K> ThenBy<T, K>(
        this IEqualityComparer<T> equalityComparer,
        Func<T, K> keyFunc)
    {
        return new KeyEqualityComparer<T, K>(keyFunc, equalityComparer);
    }
}

public struct KeyEqualityComparer<T, K>: IEqualityComparer<T>
{
    public KeyEqualityComparer(
        Func<T, K> keyFunc,
        IEqualityComparer<T> equalityComparer = null)
    {
        KeyFunc = keyFunc;
        EqualityComparer = equalityComparer;
    }

    public bool Equals(T x, T y)
    {
        return ((EqualityComparer == null) || EqualityComparer.Equals(x, y)) &&
                EqualityComparer<K>.Default.Equals(KeyFunc(x), KeyFunc(y));
    }

    public int GetHashCode(T obj)
    {
        var hash = EqualityComparer<K>.Default.GetHashCode(KeyFunc(obj));

        if (EqualityComparer != null)
        {
            var hash2 = EqualityComparer.GetHashCode(obj);

            hash ^= (hash2 << 5) + hash2;
        }

        return hash;
    }

    public readonly Func<T, K> KeyFunc;
    public readonly IEqualityComparer<T> EqualityComparer;
}

More details is on our site: IEqualityComparer in LINQ.

风苍溪 2024-07-19 11:50:03

如果您不想将 MoreLinq 库添加到项目中只是为了获得 DistinctBy 功能,那么您可以使用 Linq 的 Distinct 方法的重载获得相同的最终结果:接受 IEqualityComparer 参数。

首先创建一个通用的自定义相等比较器类,该类使用 lambda 语法对通用类的两个实例执行自定义比较:

public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
    Func<T, T, bool> _comparison;
    Func<T, int> _hashCodeFactory;

    public CustomEqualityComparer(Func<T, T, bool> comparison, Func<T, int> hashCodeFactory)
    {
        _comparison = comparison;
        _hashCodeFactory = hashCodeFactory;
    }

    public bool Equals(T x, T y)
    {
        return _comparison(x, y);
    }

    public int GetHashCode(T obj)
    {
        return _hashCodeFactory(obj);
    }
}

然后在主代码中像这样使用它:

Func<Person, Person, bool> areEqual = (p1, p2) => int.Equals(p1.Id, p2.Id);

Func<Person, int> getHashCode = (p) => p.Id.GetHashCode();

var query = people.Distinct(new CustomEqualityComparer<Person>(areEqual, getHashCode));

瞧! :)

上面假设如下:

  • 属性 Person.Id 的类型为 int
  • people 集合不包含任何 null 元素

如果集合可以包含 null,然后简单地重写 lambda 来检查 null,例如:

Func<Person, Person, bool> areEqual = (p1, p2) => 
{
    return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};

编辑

这种方法与 Vladimir Nesterovsky 的答案中的方法类似,但更简单。

它也与 Joel 的答案类似,但允许涉及多个属性的复杂比较逻辑。

但是,如果您的对象只能在 Id 上有所不同,那么另一个用户给出了正确的答案,您需要做的就是覆盖 GetHashCode() 的默认实现>Equals() 在您的 Person 类中,然后只需使用 Linq 的开箱即用的 Distinct() 方法来过滤掉任何重复项。

If you don't want to add the MoreLinq library to your project just to get the DistinctBy functionality then you can get the same end result using the overload of Linq's Distinct method that takes in an IEqualityComparer argument.

You begin by creating a generic custom equality comparer class that uses lambda syntax to perform custom comparison of two instances of a generic class:

public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
    Func<T, T, bool> _comparison;
    Func<T, int> _hashCodeFactory;

    public CustomEqualityComparer(Func<T, T, bool> comparison, Func<T, int> hashCodeFactory)
    {
        _comparison = comparison;
        _hashCodeFactory = hashCodeFactory;
    }

    public bool Equals(T x, T y)
    {
        return _comparison(x, y);
    }

    public int GetHashCode(T obj)
    {
        return _hashCodeFactory(obj);
    }
}

Then in your main code you use it like so:

Func<Person, Person, bool> areEqual = (p1, p2) => int.Equals(p1.Id, p2.Id);

Func<Person, int> getHashCode = (p) => p.Id.GetHashCode();

var query = people.Distinct(new CustomEqualityComparer<Person>(areEqual, getHashCode));

Voila! :)

The above assumes the following:

  • Property Person.Id is of type int
  • The people collection does not contain any null elements

If the collection could contain nulls then simply rewrite the lambdas to check for null, e.g.:

Func<Person, Person, bool> areEqual = (p1, p2) => 
{
    return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};

EDIT

This approach is similar to the one in Vladimir Nesterovsky's answer but simpler.

It is also similar to the one in Joel's answer but allows for complex comparison logic involving multiple properties.

However, if your objects can only ever differ by Id then another user gave the correct answer that all you need to do is override the default implementations of GetHashCode() and Equals() in your Person class and then just use the out-of-the-box Distinct() method of Linq to filter out any duplicates.

∞觅青森が 2024-07-19 11:50:03

覆盖 Equals(object obj)GetHashCode() 方法:

class Person
{
    public int Id { get; set; }
    public int Name { get; set; }

    public override bool Equals(object obj)
    {
        return ((Person)obj).Id == Id;
        // or: 
        // var o = (Person)obj;
        // return o.Id == Id && o.Name == Name;
    }
    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

然后调用:

List<Person> distinctList = new[] { person1, person2, person3 }.Distinct().ToList();

Override Equals(object obj) and GetHashCode() methods:

class Person
{
    public int Id { get; set; }
    public int Name { get; set; }

    public override bool Equals(object obj)
    {
        return ((Person)obj).Id == Id;
        // or: 
        // var o = (Person)obj;
        // return o.Id == Id && o.Name == Name;
    }
    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

and then just call:

List<Person> distinctList = new[] { person1, person2, person3 }.Distinct().ToList();
还给你自由 2024-07-19 11:50:03

与其他 .NET 版本兼容的最佳方法是重写 Equals 和 GetHash 来处理此问题(请参阅 Stack Overflow 问题此代码返回不同的值。但是,我想要的是返回强类型集合而不是匿名类型),但如果您需要通用的东西在您的代码中,本文中的解决方案非常棒。

The best way to do this that will be compatible with other .NET versions is to override Equals and GetHash to handle this (see Stack Overflow question This code returns distinct values. However, what I want is to return a strongly typed collection as opposed to an anonymous type), but if you need something that is generic throughout your code, the solutions in this article are great.

别念他 2024-07-19 11:50:03
List<Person>lst=new List<Person>
        var result1 = lst.OrderByDescending(a => a.ID).Select(a =>new Player {ID=a.ID,Name=a.Name} ).Distinct();
List<Person>lst=new List<Person>
        var result1 = lst.OrderByDescending(a => a.ID).Select(a =>new Player {ID=a.ID,Name=a.Name} ).Distinct();
千紇 2024-07-19 11:50:03

您应该能够覆盖 person 上的 Equals,以实际对 Person.id 执行 Equals。 这应该会导致您所追求的行为。

You should be able to override Equals on person to actually do Equals on Person.id. This ought to result in the behavior you're after.

青春如此纠结 2024-07-19 11:50:03

如果您使用旧的.NET版本,其中未内置扩展方法,那么您可以定义自己的扩展方法:

public static class EnumerableExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
    {
        return enumerable.GroupBy(keySelector).Select(grp => grp.First());
    }
}

使用示例:

var personsDist = persons.DistinctBy(item => item.Name);

If you use old .NET version, where the extension method is not built-in, then you may define your own extension method:

public static class EnumerableExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> enumerable, Func<T, TKey> keySelector)
    {
        return enumerable.GroupBy(keySelector).Select(grp => grp.First());
    }
}

Example of usage:

var personsDist = persons.DistinctBy(item => item.Name);
︶ ̄淡然 2024-07-19 11:50:03

绝对不是最有效的,但对于那些正在寻找简短答案的人来说:

list.Select(x => x.Id).Distinct().Select(x => list.First(y => x == y.Id)).ToList();

Definitely not the most efficient but for those, who are looking for a short and simple answer:

list.Select(x => x.Id).Distinct().Select(x => list.First(y => x == y.Id)).ToList();
来日方长 2024-07-19 11:50:03

请使用下面的代码尝试一下。

var Item = GetAll().GroupBy(x => x .Id).ToList();

Please give a try with below code.

var Item = GetAll().GroupBy(x => x .Id).ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文