使用linq选择distinct

Ano*_*shi 233 c# linq class list

我有班级班级

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" });
Run Code Online (Sandbox Code Playgroud)

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

[{id=1,value="a"},{ id = 2, value = "c" }]
Run Code Online (Sandbox Code Playgroud)

我怎么能用linq做到这一点?

编辑

输入,

id      value
1        a
1        b
2        c
3        d
3        e
Run Code Online (Sandbox Code Playgroud)

出来应该是,

id      value
1        a
2        c
3        d
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*ane 487

myList.GroupBy(test => test.id)
      .Select(grp => grp.First());
Run Code Online (Sandbox Code Playgroud)

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

var result = myList.GroupBy(test => test.id)
                   .Select(grp => grp.First())
                   .ToList();
Run Code Online (Sandbox Code Playgroud)

但是一个人通常更IEnumerable喜欢使用而不是IList上面的Linq被懒惰地评估:它实际上并没有完成所有的工作,直到可枚举被迭代.当你打电话时ToList,实际上走了整个可枚举的强迫所有工作都要提前完成.(如果你的数字可以无限长,可能会花一点时间.)

这个建议的另一面是,每当你列举这样一个IEnumerable评估它的工作时,必须重新完成.所以,你需要决定每个案例是否是更好地与懒洋洋地评估工作IEnumerable或将其实现为List,Set,Dictionary或诸如此类的东西.

  • 仅供参考:除非您再次将其转换回列表,否则无法使用.GroupBy().选择(First())将生成一个可相关的,你会得到一个转换错误.这样做:myList.GroupBy(test => test.id).Select(group => group.First()).ToList(); (6认同)
  • 嘿,尤努斯。感谢您的小意见。我可以通过使用您的代码并更改List内容来使IEnumerable工作:IEnumerable &lt;EDI_RAW_TCR&gt; rows = dc.dc中的c.EDI_RAW_TCRs,其中c.Batch_ID == 20830选择c; IEnumerable &lt;EDI_RAW_TCR&gt; raws =行; raws = rows.GroupBy(t =&gt; t.LabID).Select(group =&gt; group.First()); (3认同)
  • 在C#中,它需要.FirstOrDefault()而不是.First() (3认同)
  • @ Sruit,C#不需要这样做,但是如果您尝试在存储库中执行此操作,EF可能会让您头疼。 (3认同)
  • 并且您必须定义newList。然后将结果设置为此newList。否则,分组将不起作用。这对我有用。'List &lt;LinqTest&gt; newList =新列表&lt;LinqTest&gt;(); newList = myList.GroupBy(test =&gt; test.id).Select(group =&gt; group.First());' (2认同)

Dan*_*rth 109

使用morelinq你可以使用DistinctBy:

myList.DistinctBy(x => x.id);
Run Code Online (Sandbox Code Playgroud)

否则,您可以使用组:

myList.GroupBy(x => x.id)
      .Select(g => g.First());
Run Code Online (Sandbox Code Playgroud)

  • 完全不知道这个包需要什么好人 (2认同)
  • 哪个更快? (2认同)

Tim*_*ter 54

你应该覆盖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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以使用Distinct:

List<LinqTest> uniqueIDs = myList.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)


Tim*_*ers 24

myList.GroupBy(i => i.id).Select(group => group.First())
Run Code Online (Sandbox Code Playgroud)