Cara mendapatkan catatan pertama di setiap grup menggunakan Linq

133

Mempertimbangkan catatan berikut:

   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

Saya ingin mengelompokkan berdasarkan pada F1bidang dan mengurutkan berdasarkan Iddan mendapatkan semua bidang dari catatan pertama grup yang mirip dengan catatan ini:

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

Bagaimana saya bisa melakukan ini menggunakan LINQ?

Arian
sumber

Jawaban:

127
    var res = from element in list
              group element by element.F1
                  into groups
                  select groups.OrderBy(p => p.F2).First();
Alireza
sumber
4
Senang saya menemukan ini. Saya mendapat pesan kesalahan "Metode 'Pertama' hanya dapat digunakan sebagai operasi permintaan akhir. Pertimbangkan menggunakan metode 'FirstOrDefault' dalam contoh ini sebagai gantinya." dari teladan Anda. Hanya operasi pada daftar yang saya lakukan setelah kueri meneruskan myResult.ToList () ke suatu metode. Menggunakan FirstOrDefault menyelesaikannya
aghost
Apakah itu OrderBy(p => p.Id), mereka menginginkannya dipesan dengan ID bukan kolom tahun.
Mike Flynn
Bisakah Anda memberikan bantuan untuk ini: stackoverflow.com/questions/44764687/…
Si8
Bagaimana jika ingin mengambil item pertama dan terakhir dari grup?
Sandeep Pandey
176
var result = input.GroupBy(x=>x.F1,(key,g)=>g.OrderBy(e=>e.F2).First());
Raja Raja
sumber
2
Ini menunjukkan saya cara menggunakan sintaks Fluent. The overloads untuk GroupBy muncul untuk memberikan banyak kekuatan - satu untuk menambah daftar panjang belajar!
rogersillito
1
@rogersillito itu sebabnya ini disebut kueri (Language Integrated Query - LINQ), juga GroupBy memiliki banyak kelebihan tetapi hanya ada beberapa yang umum digunakan, juga tergantung pada preferensi pribadi, seperti beberapa orang lebih suka menuliskannya sebagai .GroupBy(x=>x.F1).Select(g=>...), mungkin terlihat lebih mudah dimengerti.
Raja Raja
11
Anda harus mengganti .First()dengan .FirstOrDefault()atau Anda akan mendapatkan pengecualian:The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.
Nikolay Kostov
5
@NikolayKostov Saya tahu tentang itu, tapi saya berasumsi LINQ di sini digunakan sebagai LINQ-to-object, bukan LINQ-to-entitas, jadi kita bisa menggunakan dengan aman .First(). Pertanyaan OP itu terlihat seperti hanya peduli dengan linq-to-object, meskipun dia juga menandai pertanyaan itu linq-to-entities(tidak yakin apakah dia mengerti apa itu).
King King
1
Saya menyukai jawaban ini, Bagus.
Ajas Aju
8

Awnser @Alireza sepenuhnya benar, tetapi Anda harus memperhatikan bahwa ketika menggunakan kode ini

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

yang mirip dengan kode ini karena Anda memesan daftar dan kemudian melakukan pengelompokan sehingga Anda mendapatkan baris pertama grup

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

Sekarang jika Anda ingin melakukan sesuatu yang lebih kompleks seperti mengambil hasil pengelompokan yang sama tetapi mengambil elemen pertama dari F2 dan elemen terakhir dari F3 atau sesuatu yang lebih khusus Anda dapat melakukannya dengan mempelajari kode di bawah ini

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

Jadi, Anda akan mendapatkan sesuatu seperti

   F1            F2             F3 
 -----------------------------------
   Nima          1990           12
   John          2001           2
   Sara          2010           4
Stavros Koureas
sumber
1
Pembatas atau pemisah objek baru harus koma bukan titik dua. Harap Periksa.
Naredla Nithesh Reddy
3

Gunakan itu untuk mencapai apa yang Anda inginkan. Kemudian tentukan properti mana yang ingin Anda kembalikan.

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