如何使用Linq在每个组中获得第一条记录

时间:2013-09-25 18:55:58

标签: c# linq c#-4.0 linq-to-entities

考虑以下记录:

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

6 个答案:

答案 0 :(得分:143)

var result = input.GroupBy(x=>x.F1,(key,g)=>g.OrderBy(e=>e.F2).First());

答案 1 :(得分:113)

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

答案 2 :(得分:6)

@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

答案 3 :(得分:3)

用它来达到你想要的效果。然后决定要返回的属性。

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

答案 4 :(得分:2)

# set up input L, a list of 4 data frames
X <- BOD
names(X) <- c("Type", "X")
L <- lapply(1:4, function(i) X[-i, ])

L.Type <- lapply(L, "[", TRUE, "Type", drop = FALSE)
Reduce(merge, L.Type)$Type
## [1] 5 7

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

答案 5 :(得分:0)

另一种方式:

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