2013-09-25 114 views
72

Xét hồ sơ sau đây:Làm thế nào để có được ghi đầu tiên trong mỗi nhóm sử dụng LINQ

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 

Tôi muốn nhóm bằng cách dựa trên các lĩnh vực F1 và sắp xếp theo Id và nhận được tất cả các lĩnh vực từ kỷ lục đầu tiên của nhóm tương tự vào những hồ sơ này:

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

Tôi có thể làm điều này bằng LINQ như thế nào?

+0

Truy vấn của bạn trông như thế nào? –

+0

* Các câu hỏi yêu cầu mã phải thể hiện sự hiểu biết tối thiểu về vấn đề đang được giải quyết. Bao gồm các giải pháp đã thực hiện, tại sao chúng không hoạt động và kết quả mong đợi * – I4V

+5

Tôi thích cách câu hỏi 36 điểm với 9 mục yêu thích là "ngoài chủ đề" ... – RareNCool

Trả lời

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

Vì vậy, vui mừng tôi thấy điều này. Tôi nhận được thông báo lỗi "Phương thức 'Đầu tiên' chỉ có thể được sử dụng làm thao tác truy vấn cuối cùng.Hãy xem xét sử dụng phương pháp 'FirstOrDefault' trong ví dụ này thay thế. "Từ ví dụ của bạn. Chỉ hoạt động trên danh sách tôi đã làm sau khi truy vấn đã được chuyển myResult.ToList() vào một phương pháp. Sử dụng FirstOrDefault giải quyết nó mặc dù – aghost

+0

Nó sẽ là' OrderBy (p => p.Id) ', họ muốn nó được đặt hàng bởi ID không phải là cột năm –

+0

Bạn có thể vui lòng cung cấp một số trợ giúp cho việc này: https://stackoverflow.com/questions/44764687/how-to-use-linq- theo từng nhóm và từng cột – Si8

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

Điều này cho tôi biết cách sử dụng cú pháp Thông thạo. [Overloads for GroupBy] (http://msdn.microsoft.com/en-us/library/vstudio/system.linq.enumerable.groupby (v = vs.100) .aspx) xuất hiện để cung cấp cho bạn rất nhiều quyền lực - một để thêm vào danh sách dài của việc học! – rogersillito

+1

@rogersillito đó là lý do tại sao nó được gọi là truy vấn (Ngôn ngữ tích hợp truy vấn - LINQ), cũng GroupBy có nhiều quá tải nhưng chỉ có một vài thường được sử dụng, cũng phụ thuộc vào sở thích cá nhân, chẳng hạn như một số người thích viết nó '.GroupBy (x => x.F1). Chọn (g => ...)', có thể dễ hiểu hơn. –

+0

tương tự để lấy được bản ghi ** đầu tiên của một nhóm ** thử [this] (http://stackoverflow.com/a/3850476/2218697), hy vọng sẽ giúp ai đó. – stom

2

Các awnser của @Alireza là hoàn toàn chính xác, nhưng bạn phải chú ý rằng khi sử dụng mã này

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

đó là simillar để mã này vì bạn đặt hàng trong danh sách và sau đó làm nhóm để bạn nhận được hàng đầu tiên của nhóm

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

Bây giờ nếu bạn muốn làm điều gì đó phức tạp hơn như lấy kết quả phân nhóm tương tự nhưng lấy phần tử đầu tiên của F2 và yếu tố cuối cùng của F3 hoặc một cái gì đó tùy chỉnh nhiều hơn bạn có thể làm điều đó bằng cách studing mã dưới đây

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

Vì vậy, bạn sẽ nhận được một cái gì đó giống như

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

Sử dụng nó để đạt được những gì bạn muốn. Sau đó quyết định thuộc tính nào bạn muốn trả lại.

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