How to get first record in each group using Linq

129,566

Solution 1

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

Solution 2

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

Solution 3

The awnser of @Alireza is totally correct, but you must notice that when using this code

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

which is simillar to this code because you ordering the list and then do the grouping so you are getting the first row of groups

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

Now if you want to do something more complex like take the same grouping result but take the first element of F2 and the last element of F3 or something more custom you can do it by studing the code bellow

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

So you will get something like

   F1            F2             F3 
 -----------------------------------
   Nima          1990           12
   John          2001           2
   Sara          2010           4

Solution 4

Use it to achieve what you want. Then decide which properties you want to return.

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

Solution 5

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

Use .AsEnumerable() after OrderBy()

Share:
129,566

Related videos on Youtube

Arian
Author by

Arian

Please vote-up this thread: RDLC Report Viewer for Visual Studio 2022

Updated on September 15, 2021

Comments

  • Arian
    Arian over 2 years

    Considering the following records:

       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
    

    I want to group by based on the F1 field and sort by Id and get all fields from the first record of group similar to these records:

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

    How can I do this using linq?

  • rogersillito
    rogersillito almost 10 years
    This showed me the way using Fluent syntax. The overloads for GroupBy appear to give you a lot of power - one to add to the long list of learning!
  • King King
    King King almost 10 years
    @rogersillito that's why it's called a query (Language Integrated Query - LINQ), also the GroupBy has many overloads but there are just a few being commonly used, also it depends on the personal preference, such as some ones prefer to write it as .GroupBy(x=>x.F1).Select(g=>...), it may look easier to understand.
  • Shaiju T
    Shaiju T over 8 years
    similar to get the Get the first record of a group try this , hope helps someone.
  • aghost
    aghost over 8 years
    So glad i found this. I got error message "The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead." from your example. Only operation on the list i did after the query was passing myResult.ToList() to a method. Using FirstOrDefault solved it though
  • Mike Flynn
    Mike Flynn almost 8 years
    Would it be OrderBy(p => p.Id), they wanted it ordered by ID not the year column.
  • Nikolay Kostov
    Nikolay Kostov over 7 years
    You should replace .First() with .FirstOrDefault() or you will get the exception: The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.
  • King King
    King King over 7 years
    @NikolayKostov I know about that, but I assumed the LINQ here is used as LINQ-to-object, not LINQ-to-entities, so we can safely use .First(). The OP's question looks really like just caring about linq-to-object, although he also tagged the question with linq-to-entities (not sure if he understood what that is).
  • Si8
    Si8 almost 7 years
    Can you please provider some assistance for this: stackoverflow.com/questions/44764687/…
  • user1566694
    user1566694 over 6 years
    i like this answer except for the fact that i cant make any sense out of it or use it
  • Ajas Aju
    Ajas Aju almost 6 years
    I liked this answers,Nice one.
  • Naredla Nithesh Reddy
    Naredla Nithesh Reddy almost 5 years
    The delimiter or separator of the new object should be comma not semi colon.Please Check.
  • Sandeep Pandey
    Sandeep Pandey over 4 years
    What if want to retrieve the first and last item from the group?
  • Somnath Kadam
    Somnath Kadam over 3 years
    Nice part is .First() and .Last()
  • LuckyLikey
    LuckyLikey over 3 years
    possibly the First() part is nomore supported in EFCore 3.1, you might have to materialize the data first.
  • CervEd
    CervEd about 3 years
    alternatively this is equivalent input.GroupBy(x => x.F1).Select(g => g.OrderBy(x => x.F2).First())