Як отримати перший запис у кожній групі за допомогою Linq


133

Зважаючи на наступні записи:

   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?

Відповіді:


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

4
Так раді, що я знайшов це. Я отримав повідомлення про помилку "Метод" Перший "може бути використаний лише як операція остаточного запиту. Розглянемо замість цього метод" FirstOrDefault "." з вашого прикладу. Тільки операція зі списку, яку я робив після того, як запит передав myResult.ToList () методу. Використання FirstOrDefault вирішило це, хоча
1616

Як би там не було OrderBy(p => p.Id), вони хотіли, щоб його замовляли за ідентифікатором не стовпцем року.
Майк Флінн

Чи можете ви постачальник певну допомогу для цього: stackoverflow.com/questions/44764687 / ...
СІ8

Що робити, якщо ви хочете отримати перший та останній елемент із групи?
Sandeep Pandey

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

2
Це показало мені спосіб використання синтаксису Fluent. У перевантажених для GroupBy з'являється , щоб дати вам багато енергії - один , щоб додати до довгого списку навчання!
rogersillito

1
@rogersillito, тому його називають запитом (Language Integrated Query - LINQ); також GroupBy має багато перевантажень, але часто використовується декілька, також це залежить від особистих уподобань, наприклад, деякі з них вважають за краще писати як .GroupBy(x=>x.F1).Select(g=>...), це може здатися легше зрозуміти.
Король-король

11
Ви повинні замінити .First()з .FirstOrDefault()або ви отримаєте виняток:The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.
Микола Костова

5
@NikolayKostov Я знаю про це, але я припускав, що LINQ тут використовується як LINQ до об'єкта, а не LINQ до сутностей, тому ми можемо безпечно використовувати .First(). Питання ОП виглядає насправді як просто турбота про зв'язок до об'єкта, хоча він також позначив це питання linq-to-entities(не впевнений, чи розуміє він, що це таке).
Король король

1
Мені сподобалися ці відповіді.
Ajas Aju

8

Тент @Alireza абсолютно правильний, але ви повинні це помітити, використовуючи цей код

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

Розмежувач або роздільник нового об’єкта має бути комою, а не комою.
Naredla Nithesh Reddy

3

Використовуйте це для досягнення того, що ви хочете. Потім вирішіть, які властивості потрібно повернути.

yourList.OrderBy(l => l.Id).GroupBy(l => new { GroupName = l.F1}).Select(r => r.Key.GroupName)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.