2010-10-19 31 views
6

Ví dụ cụ thể của tôi khá phức tạp nhưng tôi nghĩ rằng khái niệm sẽ áp dụng như nhau cho một cái gì đó giống như một hệ thống đăng nhập vì vậy tôi sẽ sử dụng nó thay vì dễ giải thích. Đó là một ví dụ ficticious, xin đừng harp vào hoặc chịu đau đớn hơn những gì là achitectually, programatically hoặc đạo đức sai với ví dụ bản thân :)LINQ: Chọn từ IEnumerable với Distinct/GroupBy và phân loại - có thể?

Giả sử bạn có này:

class LogEntry 
{ 
    int ID; 
    int UserName; 
    datetime TimeStamp; 
    string Details; 
} 

và bạn đã kéo một bộ của dữ liệu như sau:

ID Username Timestamp Details 
1 foo  1/01/2010 Account created 
2 zip  2/02/2010 Account created 
3 bar  2/02/2010 Account created 
4 sandwich 3/03/2010 Account created 
5 bar  5/05/2010 Stole food 
6 foo  5/05/2010 Can't find food 
7 sandwich 8/08/2010 Donated food 
8 sandwich 9/09/2010 Ate more food 
9 foo  9/09/2010 Ate food 
10 bar  11/11/2010 Can't find food 

Điều tôi muốn làm chỉ chọn bản ghi cuối cùng (tức là Sắp xếp theo thời gian giảm dần) cho mỗi người dùng (ví dụ: Tên người dùng GroupBy). Tôi có thể lấy đầu của tôi xung quanh Distinct, và ở một mức độ thấp hơn GroupBy, nhưng kết hợp tất cả những điều này trong một câu lệnh đơn cũng trả về các trường/thuộc tính không phân biệt/phân nhóm và sắp xếp theo dấu thời gian cho tôi đau đầu.

gì nên đi ra với ví dụ trên là:

ID Username Timestamp Details 
2 zip  2/02/2010 Account created 
8 sandwich 9/09/2010 Ate more food 
9 foo  9/09/2010 Ate food 
10 bar  11/11/2010 Can't find food 

Tôi không muốn 'lừa' và dùng đến một cách dài dòng làm việc đó khi hiệu suất là không quan trọng ở đây và tôi tự tin vừa phải, nó có thể được thực hiện trong một câu lệnh LINQ.

+0

Bạn muốn loại cuối cùng như thế nào? – Will

Trả lời

14

Hy vọng rằng tôi LINQ-fu là đúng ngày này: =)

var results = sourceList 
    .OrderByDescending(item => item.Timestamp) 
    .GroupBy(item => item.Username) 
    .Select(grp => grp.First()) 
    .ToArray(); 

này mẫu mã sử dụng dữ liệu của bạn, và đặt hàng cuối cùng của ID, mang lại cho chính xác đầu ra tương tự như ví dụ của bạn: (nếu bạn don Đừng bận tâm định dạng thô!)

class Program 
{ 
    static void Main(string[] args) 
    { 
     var sourceItems = new[] { 
      new LogEntry {ID=1 ,UserName="foo  ", TimeStamp= new DateTime(2010 ,1,01),Details="Account created ",} , 
      new LogEntry {ID=2 ,UserName="zip  ", TimeStamp= new DateTime(2010 ,2,02),Details="Account created ",} , 
      new LogEntry {ID=3 ,UserName="bar  ", TimeStamp= new DateTime(2010 ,2,02),Details="Account created ",} , 
      new LogEntry {ID=4 ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,3,03),Details="Account created ",} , 
      new LogEntry {ID=5 ,UserName="bar  ", TimeStamp= new DateTime(2010 ,5,05),Details="Stole food  ",} , 
      new LogEntry {ID=6 ,UserName="foo  ", TimeStamp= new DateTime(2010 ,5,05),Details="Can't find food ",} , 
      new LogEntry {ID=7 ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,8,08),Details="Donated food ",} , 
      new LogEntry {ID=8 ,UserName="sandwich ", TimeStamp= new DateTime(2010 ,9,09),Details="Ate more food ",} , 
      new LogEntry {ID=9 ,UserName="foo  ", TimeStamp= new DateTime(2010 ,9,09),Details="Ate food  ",} , 
      new LogEntry {ID=10 ,UserName="bar  ", TimeStamp= new DateTime(2010,11,11),Details="Can't find food ",} , 
     }; 

     var results = sourceItems 
      .OrderByDescending(item => item.TimeStamp) 
      .GroupBy(item => item.UserName) 
      .Select(grp => grp.First()) 
      .OrderBy(item=> item.ID) 
      .ToArray(); 

     foreach (var item in results) 
     { 
      Console.WriteLine("{0} {1} {2} {3}", 
       item.ID, item.UserName, item.TimeStamp, item.Details); 
     } 
     Console.ReadKey(); 
    } 
} 


public class LogEntry 
{ 
    public int ID; 
    public string UserName; 
    public DateTime TimeStamp; 
    public string Details; 
} 
+0

Có vẻ tốt với tôi. Mặc dù nó dường như được sắp xếp theo 'ID' ở cuối. –

+0

Truyền thuyết! Cảm ơn. Thật khó chịu khi tìm ra những ví dụ đơn giản không quá đơn giản. – nathanchere

+0

@ Jeff: Chúc mừng - Tôi đã yêu cầu OP làm rõ điểm này. – Will

Các vấn đề liên quan