2010-04-24 57 views
57

我有一個像到位排序字典對於鍵

Dictionary<Person, int> 

在C#中的字典,我想那種字典到位相對於鍵(在Person類的字段)。我該怎麼做?互聯網上的每一個可用的幫助都是列表,沒有特定的詞典排序示例。任何幫助將不勝感激!

+0

我不知道我理解你的問題,因爲字典沒有以任何順序列舉?您可以遍歷鍵或值,您可以在運行時輕鬆進行排序... – 2010-04-24 18:22:41

回答

116

您無法對Dictionary<TKey, TValue>進行排序 - 它本質上是無序的。 (或者更確切地說,在條目被檢索的順序是實現特定的,你不應該依賴於它的工作版本之間的相同的方式,因爲排序是不是它的設計功能的一部分。)

可以使用SortedList<TKey, TValue>SortedDictionary<TKey, TValue>,這兩種方法都是通過鍵(按可配置的方式,如果將IEqualityComparer<T>傳遞給構造函數)進行排序 - 可能對您有用嗎?

在名稱SortedList中不太注意單詞「list」 - 它仍然是一個字典,它將鍵映射到值。它是實施內部有效地使用列表 - 所以,而不是查找哈希代碼,它執行二進制搜索。 SortedDictionary同樣基於二進制搜索,但通過樹而不是列表。

+2

但要小心使用'SortedList ',但是:如果您構建大型列表(假設項目是未預先分類)。通常你應該使用'SortedDictionary '來代替,或者使用第三方['BDictionary '](http://loyc.net/doc/code/classLoyc_1_1Collections_1_1BDictionary_3_01K_00_01V_01_4.html)來獲得類似於'SortedDictionary'的性能,而不會丟失通過索引或「查找最近的密鑰」訪問項目的能力。 – Qwertie 2016-02-26 07:04:42

6

按設計,字典不可排序。如果您在字典中需要此功能,請改爲查看SortedDictionary。

4

看看SortedDictionary嘗試,甚至有一個構造函數重載,所以你可以在自己的IComparable的通爲比較。

4

正確答案已經說明了(只是使用SortedDictionary)。

然而,如果碰巧你有一些需要保留您的收藏如字典,可以訪問詞典按鍵有序的方式,通過,例如,在列表排序鍵,​​然後使用這個列表訪問詞典。一個例子...

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

...一些代碼,填寫 「dupcheck」,然後...

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

不要忘記using System.Linq;這一點。

1

雖然Dictionary是作爲散列表實現的,但SortedDictionary是作爲紅黑樹實現的。

如果您沒有利用算法中的順序,只需要在輸出前對數據進行排序,則使用SortedDictionary的將對性能產生負面影響

你可以在 「排序」 像這樣的詞典:

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

由於這個答案較高的搜索配售我認爲LINQ 排序依據解決方案是值得炫耀:

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

輸出:

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 

在這個例子中,它會道理也使用ThenBy的名字:

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

然後輸出爲:

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也有OrderByDescendingThenByDescending爲那些需要它。