首页 文章

使用linq [duplicate]选择distinct

提问于
浏览
210

这个问题在这里已有答案:

我有 class 的 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做到这一点?

Edit

输入,

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

出来应该是,

id      value
1        a
2        c
3        d

即,如果重复 id ,结果应该仅在第一次出现时出现 .

4 回答

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

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

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

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

    这个建议的另一面是,每当你列举这样一个 IEnumerable 时,评估它的工作必须重新完成 . 因此,您需要为每种情况决定是否更好地使用延迟评估 IEnumerable 或将其实现为 ListSetDictionary 或诸如此类的东西 .

  • 50

    使用morelinq,您可以使用 DistinctBy

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

    否则,您可以使用组:

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

    您应该有意义地覆盖 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();
    
  • 438
    myList.GroupBy(i => i.id).Select(group => group.First())
    

相关问题