我在C#中有一本词典,如
Dictionary<Person, int>
我想根据键(类Person中的字段)对字典到位进行排序。我该怎么做?互联网上的每个可用帮助都是列表,没有特定的字典排序示例。任何帮助将非常感谢!
答案 0 :(得分:141)
你不能对Dictionary<TKey, TValue>
进行排序 - 它本身就是无序的。 (或者更确切地说,检索条目的顺序是特定于实现的。您不应该依赖它在版本之间以相同的方式工作,因为排序不是其设计功能的一部分。)
你可以使用SortedList<TKey, TValue>
或SortedDictionary<TKey, TValue>
,两者都按键排序(以可配置的方式,如果你将IEqualityComparer<T>
传递给构造函数) - 那些对你有用吗?
很少注意名称SortedList
中的“list”一词 - 它仍然是一个字典,因为它将键映射到值。内部有效地使用列表实现 - 因此,它不是通过哈希代码查找,而是进行二进制搜索。 SortedDictionary
同样基于二进制搜索,但是通过树而不是列表。
答案 1 :(得分:23)
尝试使用SortedDictionary
答案 2 :(得分:10)
已经说明了正确的答案(只使用SortedDictionary)。
但是,如果您有某些需要将您的集合保留为Dictionary,则可以按顺序访问Dictionary键,例如,通过对List中的键进行排序,然后使用此列表进行访问词典。一个例子......
Dictionary<string, int> dupcheck = new Dictionary<string, int>();
......一些代码填写&#34; dupcheck&#34;,然后......
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;
。
答案 3 :(得分:7)
按照设计,字典不可排序。如果您需要在字典中使用此功能,请查看SortedDictionary。
答案 4 :(得分:4)
看看SortedDictionary
,甚至还有一个构造函数重载,所以你可以传入你自己的IComparable进行比较。
答案 5 :(得分:3)
虽然Dictionary是作为哈希表实现的,但SortedDictionary实现为红黑树。
如果您没有利用算法中的顺序,只需要在输出前对数据进行排序,使用SortedDictionary会对性能产生负面影响。
你可以&#34;排序&#34;像这样的字典:
Dictionary<string, int> dictionary = new Dictionary<string, int>();
// algorithm
return new SortedDictionary<string, int>(dictionary);
答案 6 :(得分:1)
由于这个答案很高,我认为LINQ OrderBy 解决方案值得展示:
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还有 OrderByDescending 和 ThenByDescending 。