相对于键对字典进行排序

Sou*_*ver 71 c# sorting dictionary

我在C#中有一本字典

Dictionary<Person, int>
Run Code Online (Sandbox Code Playgroud)

我想那种字典到位相对于键(在Person类的字段).我该怎么做?互联网上的每个可用帮助都是列表,没有特定的字典排序示例.任何帮助将非常感谢!

Jon*_*eet 145

你无法排序Dictionary<TKey, TValue>- 它本身就是无序的.(或者更确切地说,检索条目的顺序是特定于实现的.您不应该依赖它在版本之间以相同的方式工作,因为排序不是其设计功能的一部分.)

可以使用SortedList<TKey, TValue>或者SortedDictionary<TKey, TValue>两者都按键排序(以可配置的方式,如果你传入IEqualityComparer<T>构造函数) - 那些对你有用吗?

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

  • 但要注意使用`SortedList <K,V>`:如果你建立一个大的列表(假设项目没有预先排序),它会非常慢.通常你应该使用`SortedDictionary <K,V>`,或者使用第三方[`BDictionary <K,V>`](http://loyc.net/doc/code/classLoyc_1_1Collections_1_1BDictionary_3_01K_00_01V_01_4.html)来获得性能类似于`SortedDictionary`而不会失去按索引访问项目或"查找最近的密钥"的能力. (2认同)

Chr*_*s O 24

尝试使用SortedDictionary

  • 在回答时,你比[上帝](/sf/users/1585951/)慢了21秒.那不是那么糟糕. (3认同)

小智 12

已经说明了正确的答案(只使用SortedDictionary).

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

Dictionary<string, int> dupcheck = new Dictionary<string, int>();
Run Code Online (Sandbox Code Playgroud)

...一些填写"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]);
  }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记using System.Linq;这一点.


Sco*_*man 7

根据设计,字典不可排序.如果您需要在字典中使用此功能,请查看SortedDictionary.


Dra*_*ex_ 6

Dictionary 是作为哈希表实现的,而 SortedDictionary 是作为红黑树实现的。

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

您可以像这样对字典进行“排序”:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
// algorithm
return new SortedDictionary<string, int>(dictionary);
Run Code Online (Sandbox Code Playgroud)


Dan*_*ler 6

由于这个答案的高搜索排名,我认为 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

在这个例子中,对名字也使用ThenBy是有意义的:

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

然后输出是:

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
Run Code Online (Sandbox Code Playgroud)

LINQ 还为需要它的人提供OrderByDescendingThenByDescending