如何使用Linq获取每组中的第一条记录

问题描述 投票:0回答:7

考虑以下记录:

   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 执行此操作?

c# linq c#-4.0 linq-to-entities
7个回答
237
投票
var result = input.GroupBy(x => x.F1, (key,g) => g.OrderBy(e => e.F2).First());

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

15
投票

@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

4
投票

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

yourList.OrderBy(l => l.Id).GroupBy(l => new { GroupName = l.F1}).Select(r => r.Key.GroupName)

3
投票

另一种方式:

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());

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

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


-2
投票

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

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 John

❊ 从技术上讲,它是 IEnumerable>

© www.soinside.com 2019 - 2024. All rights reserved.