如何使用LINQ从对象列表中获取属性的唯一列表?

190

我试图使用LINQ返回一个id列表,这个列表是由一个对象列表生成的,其中id是一个属性。我想要做到的是不必循环遍历每个对象,就能够提取出我发现的唯一id。

我有一个类型为MyClass的对象列表,并且这个类的一个属性是ID。

public class MyClass
{
  public int ID { get; set; }
}
我想编写一个LINQ查询来返回那些ID的列表。给定一个,如何做到这一点,以便返回ids的IEnumerable?我相信可以使用LINQ在一两行代码中完成,而不是通过循环遍历MyClass列表中的每个项并将唯一值添加到列表中。

3
请注意,在 MoreLinq 中有一个 DistinctBy 方法,它将根据 ID 给出独特的 MyClass。用法:var distincts = list.DistinctBy(x => x.ID); - nawfal
5个回答

352
IEnumerable<int> ids = list.Select(x=>x.ID).Distinct();

2
哇!我以为这很简单...我只是想不到。看来我需要花更多时间熟悉Linq。 - mezoid

30

6
小小的命名问题:它不是一个 ID 的“列表”,而是一个延迟计算的 IEnumerable<int>。当然,如果你调用 .ToList(),它就会被实际计算出来了。 - Marc Gravell
@Marc,能否简单解释一下延迟求值的概念?谢谢:D - masfenix
3
"Lazy eval" 的意思是直到实际使用时才进行操作。在这种情况下,选择ID并仅选择不同的ID并不一定在执行此答案中的语句时完成。它将在您实际开始遍历idList时执行,例如在 foreach 循环中。 - Mark Meuer

13

使用直接的LINQ,结合Distinct()扩展:

var idList = (from x in yourList select x.ID).Distinct();

2
int[] numbers = {1,2,3,4,5,3,6,4,7,8,9,1,0 };
var nonRepeats = (from n in numbers select n).Distinct();

foreach (var d in nonRepeats)
{

    Response.Write(d);
}

输出

1234567890


2
不回答问题,即使回答了也没有添加新内容。 - nawfal

2

在使用 Distinct 方法时,我们需要将其转换为 IEnumerable 类型。如果列表是 <T> 模型,则需要编写如下代码:

 IEnumerable<T> ids = list.Select(x => x).Distinct();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接