使用linq选择distinct

时间:2013-10-16 14:33:50

标签: c# linq list class

我有一个班级列表

public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
}


List<LinqTest> myList = new List<LinqTest>();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });

我只需从该列表中选择不同的ID。 即,我的结果列表应该只包含

[{id=1,value="a"},{ id = 2, value = "c" }]

如何使用linq执行此操作?

修改

输入,

id      value
1        a
1        b
2        c
3        d
3        e

输出应该是,

id      value
1        a
2        c
3        d

即,如果重复id,结果应该只出现第一次。

4 个答案:

答案 0 :(得分:454)

myList.GroupBy(test => test.id)
      .Select(grp => grp.First());

编辑:将IEnumerable<>变成List<>对许多人来说似乎是一个谜,你可以简单地写一下:

var result = myList.GroupBy(test => test.id)
                   .Select(grp => grp.First())
                   .ToList();

但是最好不要使用IEnumerable而不是IList,因为上面的Linq被懒惰地评估了:在重复枚举之前,它实际上并没有完成所有的工作。当你致电ToList时,它实际上走了整个可枚举的强制,迫使所有的工作都提前完成。 (如果你的数字可以无限长,可能需要一段时间。)

这个建议的另一面是每次枚举这样的IEnumerable时,必须重新完成评估它的工作。因此,您需要针对每种情况决定是否更好地使用延迟评估的IEnumerable或将其实现为ListSetDictionary或诸如此类。< / p>

答案 1 :(得分:104)

使用morelinq,您可以使用DistinctBy

myList.DistinctBy(x => x.id);

否则,您可以使用组:

myList.GroupBy(x => x.id)
      .Select(g => g.First());

答案 2 :(得分:52)

您应该有意义地覆盖EqualsGetHashCode,在这种情况下要比较ID:

public class LinqTest
{
    public int id { get; set; }
    public string value { get; set; }

    public override bool Equals(object obj)
    {
        LinqTest obj2 = obj as LinqTest;
        if (obj2 == null) return false;
        return id == obj2.id;
    }

    public override int GetHashCode()
    {
        return id;
    }
}

现在您可以使用Distinct

List<LinqTest> uniqueIDs = myList.Distinct().ToList();

答案 3 :(得分:23)

myList.GroupBy(i => i.id).Select(group => group.First())