2010-04-24 38 views
57

Tôi có một cuốn từ điển trong C# nhưSắp xếp một điển tại chỗ đối với các phím với

Dictionary<Person, int> 

và tôi muốn sắp xếp mà điển tại chỗ đối với phím (một lĩnh vực trong lớp Person) với. Tôi làm nó như thế nào? Mọi trợ giúp có sẵn trên internet là danh sách không có ví dụ cụ thể về việc sắp xếp từ điển. Bất cứ sự giúp đỡ nào cũng được đánh giá cao!

+0

Tôi không chắc mình hiểu câu hỏi của bạn vì từ điển không được liệt kê theo thứ tự nào? Bạn có thể lặp lại thông qua các khóa, hoặc các giá trị, mà bạn có thể dễ dàng sắp xếp trên bay ... –

Trả lời

116

Bạn không thể sắp xếp Dictionary<TKey, TValue> - vốn không có thứ tự. (Hay đúng hơn, thứ tự các mục được truy xuất là cụ thể cho từng mục đích. Bạn không nên dựa vào nó làm việc theo cách tương tự giữa các phiên bản, vì thứ tự không phải là một phần của chức năng được thiết kế của nó.)

Bạn can sử dụng SortedList<TKey, TValue> hoặc SortedDictionary<TKey, TValue>, cả hai đều sắp xếp theo khóa (theo cách có thể định cấu hình, nếu bạn chuyển một số IEqualityComparer<T> vào hàm tạo) - có thể sử dụng chúng cho bạn không?

Chú ý ít đến từ "danh sách" trong tên SortedList - nó vẫn là từ điển ở chỗ nó ánh xạ khóa tới giá trị. Đó là được triển khai bằng danh sách nội bộ, hiệu quả - vì vậy thay vì tra cứu bằng mã băm, nó thực hiện tìm kiếm nhị phân. SortedDictionary tương tự dựa trên các tìm kiếm nhị phân, nhưng thông qua một cây thay vì danh sách.

+2

Hãy cẩn thận khi sử dụng 'SortedList ', mặc dù: nó sẽ rất chậm nếu bạn xây dựng một danh sách lớn (giả sử các mục là không được sắp xếp trước). Thông thường, bạn nên sử dụng 'SortedDictionary ' thay vào đó hoặc sử dụng bên thứ ba ['BDictionary '] (http://loyc.net/doc/code/classLoyc_1_1Collections_1_1BDictionary_3_01K_00_01V_01_4.html) để có được hiệu suất tương tự như 'SortedDictionary' mà không làm mất khả năng truy cập các mục theo chỉ mục hoặc "tìm khóa gần nhất". – Qwertie

6

Theo thiết kế, từ điển không thể sắp xếp được. Nếu bạn cần khả năng này trong từ điển, hãy xem SortedDictionary thay thế.

4

Hãy xem SortedDictionary, thậm chí có một tình trạng quá tải nhà xây dựng để bạn có thể vượt qua trong IComparable của riêng bạn cho các so sánh.

4

Câu trả lời đúng đã được nêu rõ (chỉ cần sử dụng SortedDictionary).

Tuy nhiên, nếu tình cờ bạn cần giữ lại bộ sưu tập của mình làm Từ điển, bạn có thể truy cập các phím Từ điển theo cách được sắp xếp, ví dụ, đặt các khóa trong Danh sách, sau đó sử dụng danh sách này truy cập từ điển. Một ví dụ ...

Dictionary<string, int> dupcheck = new Dictionary<string, int>(); 

... một số mã mà điền vào "dupcheck", sau đó ...

if (dupcheck.Count > 0) { 
    Console.WriteLine("\ndupcheck (count: {0})\n----", dupcheck.Count); 
    var keys_sorted = dupcheck.Keys.ToList(); 
    keys_sorted.Sort(); 
    foreach (var k in keys_sorted) { 
    Console.WriteLine("{0} = {1}", k, dupcheck[k]); 
    } 
} 

Đừng quên using System.Linq; cho việc này.

1

Trong khi từ điển được triển khai dưới dạng bảng băm, SortedDictionary được triển khai dưới dạng cây đỏ-đen.

Nếu bạn không tận dụng thứ tự trong thuật toán của mình và chỉ cần sắp xếp dữ liệu trước khi xuất, sử dụng SortedDictionary sẽ có tác động tiêu cực đến hiệu suất.

Bạn có thể "loại" từ điển như thế này:

Dictionary<string, int> dictionary = new Dictionary<string, int>(); 
// algorithm 
return new SortedDictionary<string, int>(dictionary); 
0

Do đó câu trả lời đặt tìm kiếm cao Tôi nghĩ giải pháp LINQ OrderBy là giá trị thể hiện:

class Person 
{ 
    public Person(string firstname, string lastname) 
    { 
     FirstName = firstname; 
     LastName = lastname; 
    } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

static void Main(string[] args) 
{ 
    Dictionary<Person, int> People = new Dictionary<Person, int>(); 

    People.Add(new Person("John", "Doe"), 1); 
    People.Add(new Person("Mary", "Poe"), 2); 
    People.Add(new Person("Richard", "Roe"), 3); 
    People.Add(new Person("Anne", "Roe"), 4); 
    People.Add(new Person("Mark", "Moe"), 5); 
    People.Add(new Person("Larry", "Loe"), 6); 
    People.Add(new Person("Jane", "Doe"), 7); 

    foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName)) 
    { 
     Debug.WriteLine(person.Key.LastName + ", " + person.Key.FirstName + " - Id: " + person.Value.ToString()); 
    } 
} 

Output:

Doe, John - Id: 1 
Doe, Jane - Id: 7 
Loe, Larry - Id: 6 
Moe, Mark - Id: 5 
Poe, Mary - Id: 2 
Roe, Richard - Id: 3 
Roe, Anne - Id: 4 

Trong ví dụ này, nó sẽ làm cho tinh thần để còn sử dụng ThenBy cho tên đầu tiên:

foreach (KeyValuePair<Person, int> person in People.OrderBy(i => i.Key.LastName).ThenBy(i => i.Key.FirstName)) 

Sau đó, đầu ra là:

Doe, Jane - Id: 7 
Doe, John - Id: 1 
Loe, Larry - Id: 6 
Moe, Mark - Id: 5 
Poe, Mary - Id: 2 
Roe, Anne - Id: 4 
Roe, Richard - Id: 3 

LINQ cũng có OrderByDescendingThenByDescending cho những người cần nó.

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