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

C# 根据关键字对词典进行排序,c#,sorting,dictionary,C#,Sorting,Dictionary,我有一本类似C的字典 字典 我想根据键(类Person中的一个字段)对字典进行排序。我怎么做?互联网上的每一个可用的帮助都是列表,没有特定的词典就地排序示例。任何帮助都将不胜感激 您无法对词典进行排序——它本身就是无序的。(或者更确切地说,条目的检索顺序是特定于实现的。您不应该依赖它在版本之间以相同的方式工作,因为排序不是其设计功能的一部分。) 您可以使用或,这两种按键排序(如果您将IEqualityComparer传递到构造函数中,则以可配置的方式),它们是否对您有用 不要太注意名字中的单词

我有一本类似C的字典

字典

我想根据键(类Person中的一个字段)对字典进行排序。我怎么做?互联网上的每一个可用的帮助都是列表,没有特定的词典就地排序示例。任何帮助都将不胜感激

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

您可以使用或,这两种按键排序(如果您将
IEqualityComparer
传递到构造函数中,则以可配置的方式),它们是否对您有用


不要太注意名字中的单词“list”
SortedList
——它仍然是一本字典,因为它将键映射到值。它在内部有效地使用一个列表来实现——因此,它不通过哈希代码进行查找,而是进行二进制搜索
SortedDictionary类似地基于二进制搜索,但通过树而不是列表。

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

尝试使用查看
SortedDictionary
,甚至还有一个构造函数重载,因此您可以传入自己的IComparable进行比较。

正确答案已经说明(只需使用SortedDictionary)


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

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

不要忘记
使用System.Linq

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

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

您可以按如下方式对词典进行“排序”:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
// algorithm
return new SortedDictionary<string, int>(dictionary);
Dictionary Dictionary=newdictionary();
//算法
返回新的分类词典(字典);

由于此答案的搜索排名较高,我认为LINQOrderBy解决方案值得展示:

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());
    }
}
在本例中,也可以使用然后使用作为名字:

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

LINQ还有降序的然后降序的功能,可供需要它的人使用。

我不确定我是否理解你的问题,因为字典不是按任何顺序列举的?您可以遍历键或值,您可以轻松地对它们进行动态排序……这不可能是您真正想要的。数组可以就地排序,因为排序数组的结果是数组。但字典不是数组,因此不能用对其条目进行排序的结果替换它。对条目进行排序并将结果保存在数组或列表中。而被接受的答案可能不是你想要的。。。从SortedList或SortedDictionary中输入和访问条目比从字典中输入和访问条目要慢得多。但是,使用
SortedList
时要小心:如果您构建一个大列表(假设条目未预排序),则输入和访问条目的速度会非常慢。通常,您应该使用
SortedDictionary
,或者使用第三方来获得与
SortedDictionary
类似的性能,而不会失去按索引或“查找最近键”访问项目的能力。二进制搜索代替在排序键旁边维护哈希有什么好处?如果我不是仅仅做有序枚举,为什么我要关心元素是有序的?如果我更关心单个元素的查找,但是第二次想要基于键顺序进行枚举,那么我是否需要管理一个单独的键列表?如果这是我想要的用途,
SortedList
&
SortedDictionary
实际上是错误的工具,对吗?也就是说,如果我真的只想对字典中的键进行排序,该怎么办?@ruffin:好处是避免了复杂性。是的,据我所知,没有内置的“排序和散列”集合。请注意,这样的集合更难使用,也更难构建-必须提供相等比较和哈希代码函数以及排序函数。当然,保存这两个集合还需要内存成本。您需要衡量实际数据的二进制搜索与散列查找的成本-您可能会发现,除非您的集合很大,否则它实际上并不重要。@ruffin“二进制搜索比在排序键旁边维护散列有什么好处?”--哈希表的内存以及添加或删除条目时维护哈希表的时间。“为什么我关心元素的顺序”——如果您不关心元素的顺序,那么只需使用字典(我通常建议使用字典而不是SortedList或SortedDictionary)“但第二,我希望基于键顺序进行枚举”——当您偶尔需要时,对枚举的键值对进行排序是很简单的:dict.OrderBy(kv=>kv.Key)@ruffin“如果我真的只想在适当的位置对字典键进行排序怎么办?”--没有这样的事情--这是一个类别错误。数组可以在适当的位置进行排序……数组以外的任何东西都不能排序。(好吧,除了具有可变节点的链表,但在适当的位置对这样的事情进行排序将是愚蠢且非常昂贵的。)当然,你可以做一些事情,比如
var-array=dict.Keys.ToArray();array.Sort();
你的回答速度比21秒还慢。这并不坏。“如果碰巧你需要将你的收藏保留为字典”--保留它的明显原因是它具有更快的插入、删除和查找速度_
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
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