关于C#:根据键对字典进行排序

Sorting a Dictionary in place with respect to keys

我有一本C语言的字典

1
Dictionary<Person, int>

我想把字典按照键(class person中的一个字段)进行排序。我该怎么做?互联网上所有可用的帮助都是列表帮助,没有特定的字典就地排序示例。任何帮助都将不胜感激!


你不能对一个Dictionary进行排序——它本质上是无序的。(或者更确切地说,条目的检索顺序是特定于实现的。您不应该以相同的方式在版本之间工作,因为排序不是其设计功能的一部分。)

您可以使用SortedListSortedDictionary,这两种类型都是按键排序的(以可配置的方式,如果您将IEqualityComparer传递到构造函数中),这些可能对您有用吗?

很少注意名称SortedList中的单词"list"——它仍然是一个字典,因为它将键映射到值。它是在内部使用一个列表来实现的,非常有效——因此,它不使用哈希代码进行查找,而是进行二进制搜索。SortedDictionary同样基于二进制搜索,但通过树而不是列表。


尝试使用SortedDictionary


正确的答案已经说明(只使用sorteddictionary)。

但是,如果您偶然需要将集合保留为字典,则可以按顺序访问字典键,例如,通过对列表中的键进行排序,然后使用此列表访问字典。一个例子…

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

…一些填充"dupcheck"的代码,然后…

1
2
3
4
5
6
7
8
9
10
if (dupcheck.Count > 0) {
  Console.WriteLine("
dupcheck (count: {0})
----"
, dupcheck.Count);
  var keys_sorted = dupcheck.Keys.ToList();
    keys_sorted.Sort();
  foreach (var k in keys_sorted) {
    Console.WriteLine("{0} = {1}", k, dupcheck[k]);
  }
}

别忘了这件事。


按设计,字典是不可排序的。如果您在字典中需要此功能,请查看SortedDictionary。


看看SortedDictionary,甚至还有一个构造函数重载,这样您就可以传入自己的IComparable进行比较。


当字典实现为哈希表时,SortedDictionary实现为红黑树。

如果不利用算法中的顺序,只需要在输出前对数据进行排序,那么使用sortedDictionary将对性能产生负面影响。

您可以这样"排序"字典:

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


由于这个答案的高搜索位置,我认为Linq Orderby解决方案值得展示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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());
    }
}

输出:

1
2
3
4
5
6
7
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是有意义的:

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

则输出为:

1
2
3
4
5
6
7
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和ByDescending。