163

考虑以下记录:

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   2           Nima          1990           11
   3           Nima          2000           12
   4           John          2001           1
   5           John          2002           2 
   6           Sara          2010           4

我想根据字段进行分组,并从类似于这些记录的组的第一条记录中F1排序并获取所有字段:Id

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   4           John          2001           1
   6           Sara          2010           4

我怎样才能使用 linq 做到这一点?

4

7 回答 7

220
var result = input.GroupBy(x => x.F1, (key,g) => g.OrderBy(e => e.F2).First());
于 2013-09-25T18:59:48.820 回答
142
var res = from element in list
          group element by element.F1
              into groups
              select groups.OrderBy(p => p.F2).First();
于 2013-09-25T19:00:18.900 回答
14

@Alireza 的 awnser 是完全正确的,但是你在使用这段代码时必须注意

var res = from element in list
          group element by element.F1
              into groups
              select groups.OrderBy(p => p.F2).First();

这与此代码类似,因为您对列表进行排序,然后进行分组,以便获得第一行组

var res = (from element in list)
          .OrderBy(x => x.F2)
          .GroupBy(x => x.F1)
          .Select()

现在,如果您想做一些更复杂的事情,例如采用相同的分组结果,但采用 F2 的第一个元素和 F3 的最后一个元素或更自定义的东西,您可以通过研究下面的代码来做到这一点

 var res = (from element in list)
          .GroupBy(x => x.F1)
          .Select(y => new
           {
             F1 = y.FirstOrDefault().F1;
             F2 = y.First().F2;
             F3 = y.Last().F3;
           });

所以你会得到类似的东西

   F1            F2             F3 
 -----------------------------------
   Nima          1990           12
   John          2001           2
   Sara          2010           4
于 2016-10-08T11:57:50.807 回答
4

用它来实现你想要的。然后决定要返回的属性。

yourList.OrderBy(l => l.Id).GroupBy(l => new { GroupName = l.F1}).Select(r => r.Key.GroupName)
于 2016-11-22T19:01:28.813 回答
2
var res = (from element in list)
      .OrderBy(x => x.F2).AsEnumerable()
      .GroupBy(x => x.F1)
      .Select()

在 OrderBy() 之后使用 .AsEnumerable()

于 2021-01-03T14:16:51.853 回答
1

其他方式:

var result = input.GroupBy(i => i.F1).Select(g => g.First());

您可以按多个字段分组:

var result = input.GroupBy(i => new {i.F1, i.F2}).Select(g => g.First());

如果您需要保持顺序,请使用查找:

var result = input.ToLookup(i => i.F1).Select(g => g.First());
于 2021-07-21T19:38:56.720 回答
-1

这并不完全是您要寻找的东西,但有时我们会寻找错误的东西,因为我们不知道存在什么。所以我的解决方案是最直观的:

var dict = 
input.OrderByDescending(x => x.Id)
     .GroupBy(x => x.F1)
     .ToDictionary(x => x.Key, x => new { x.First().F1, x.First().F2, x.First().F3});

先订购,然后分组——直截了当。现在结果将是一个键类型对的列表❊。由于我们的表已经排序,我们可以选择第一个条目。此外,我建议将结果放入带有 ID 作为访问器的字典中,这是一种访问速度非常快且仍然灵活的数据结构。现在您可以使用

dict[4].F1 // returns Nima

❊ 技术上它的 IEnumerable<IGrouping<int, yourType>>

于 2021-09-02T20:46:03.267 回答