2011-10-29 66 views
5

Xin chào Tôi có loại tra cứu lưu trữ chuỗi và int.Cách sắp xếp tra cứu?

static Lookup<string, int> lookup; 
lookup = (Lookup<string, int>)list.ToLookup(i => i.IP, i => i.Number); 

Nhưng bây giờ tôi cần sắp xếp tra cứu này bằng giá trị (số) và nhận 10 khóa hàng đầu có giá trị của chúng.

Làm cách nào có thể?

+1

Tôi đang cố gắng để hiểu điều này. Tại sao bạn đúc 'i.Number' thành' string'? – James

+0

Xin lỗi, đáng lẽ phải là int. Bây giờ tôi thay đổi nó, còn Ill đánh dấu câu trả lời khi tôi về nhà và thử nó tối nay. Rất cám ơn tất cả. – sprocket12

Trả lời

2

Tôi không chắc chắn lý do tại sao bạn đang đúc một Lookup<string, int> đến một Lookup<string, string>, nhưng câu trả lời chung bạn muốn là:

var list = new List<Test> 
    { 
      new Test { IP = "A", Number = 1 }, new Test { IP = "A", Number = 3 }, new Test { IP = "A", Number = 4 }, 
      new Test { IP = "B", Number = 1 }, new Test { IP = "B", Number = 1 }, new Test { IP = "B", Number = 1 }, 
      new Test { IP = "C", Number = 1 }, 
      new Test { IP = "D", Number = 1 }, 
      new Test { IP = "E", Number = 1 }, new Test { IP = "E", Number = 1 }, new Test { IP = "E", Number = 1 } 
    }; 

var values = list.ToLookup(s => s.IP, s => s.Number) 
       .OrderByDescending(s => s.Count()) 
       .Take(10); 
+0

Xin cảm ơn vì đã nỗ lực hơn trong việc tạo danh sách kiểm tra. – sprocket12

0

Hãy xem hàm 01QLINQ bạn có thể thực hiện một việc như Take(10) để chỉ trả về 10 kết quả. Để sắp xếp, hãy kiểm tra hàm OrderBy() chấp nhận một biểu thức lambda như một cơ chế sắp xếp. Kết hợp cả hai sẽ cung cấp cho bạn những gì bạn đang sau.

1

Go tìm một Queue ưu tiên (bạn có thể tìm thấy một tại http://www.itu.dk/research/c5/). Lặp lại quá trình tìm kiếm của bạn và chèn một mục IComparable được tạo ra từ mỗi mục trong tra cứu, vào hàng đợi ưu tiên. Chọn mười mục hàng đầu từ hàng đợi ưu tiên. Hoặc chỉ cần sắp xếp chúng theo số lượng là khóa.

var lookup = list.ToLookup(l => l.IP, l => l.Number); 
var topten = lookup.OrderByDescending(l => l.Count()) 
        .Take(10); 

foreach (var item in topten) 
{ 
    Console.WriteLine("{0}: {1}", item.Key, item.Count()); 
} 

Lưu ý rằng sắp xếp sẽ có hiệu suất O (nlogn) tốt nhất trong khi hàng đợi ưu tiên dựa trên heap sẽ có hiệu suất O (logn). Nếu bộ sưu tập không lớn, việc phân loại sẽ đơn giản hơn nếu được hỗ trợ sẵn cho nó và không cần một lớp trung gian để hỗ trợ việc thực hiện hàng đợi ưu tiên.

+0

Xin chào, câu trả lời của bạn là chính xác, tuy nhiên tôi không thể đánh dấu hai câu trả lời là chính xác. Rất cảm ơn vì sự giúp đỡ của bạn. – sprocket12

2

Rất tiếc, các phần tử bên trong một Lookup không thể được sắp xếp lại.

Nhưng phương thức ToLookup() có thuộc tính tốt đẹp mà các phần tử trong tất cả các nhóm có cùng thứ tự như các phần tử trong chuỗi gốc.

Điều này có nghĩa rằng với một số thể dục LINQ, bạn có thể đạt được những gì bạn muốn bằng cách sử dụng groupby:

var l = (from l in list 
     // group elements by key 
     group l by l.IP into g 
     // for each group order the elements and take top 10 
     select new { g.Key, Items = g.OrderBy(g1 => g1.Number).Take(10)} into g2 
     // flaten group into an enumerable using select many 
     from g in g2.Items 
     select g) 
     // get the desired lookup containing the top 10 ordered elements for each key 
     .ToLookup(g => g.IP, g => g.Number); 
+0

Ohhh, Ngài muốn có mười chìa khóa hàng đầu và không phải là số mười hàng đầu tính? Tôi hoàn toàn bỏ lỡ điều đó. –

+0

"các phần tử trong tất cả các nhóm có cùng thứ tự như các phần tử trong chuỗi gốc" - điều đó rất hữu ích. – Homer