你如何按价值排序字典?

我常常须要按值排序字典,包括键和值。 例如,我有一个单词和各自频率的哈希,我想按频率排序。 数据库

有一个SortedList适用于单个值(好比频率),我想将它映射回单词。 数据结构

SortedDictionary按键排序 ,而不是值。 有些人诉诸于自定义课程 ,可是有更清洁的方法吗? oop


#1楼

排序值 spa

这显示了如何对Dictionary中的值进行排序。 咱们看到一个能够在Visual Studio中编译并运行的控制台程序。 它为Dictionary添加了键,而后按其值对它们进行排序。 请记住,Dictionary实例最初不以任何方式排序。 咱们在查询语句中使用LINQ orderby关键字。 指针

对字典[C#]进行排序的OrderBy子句程序 code

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary<string, int>(5);
        dictionary.Add("cat", 1);
        dictionary.Add("dog", 0);
        dictionary.Add("mouse", 5);
        dictionary.Add("eel", 3);
        dictionary.Add("programmer", 2);

        // Order by values.
        // ... Use LINQ to specify sorting by value.
        var items = from pair in dictionary
                orderby pair.Value ascending
                select pair;

        // Display results.
        foreach (KeyValuePair<string, int> pair in items)
        {
            Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
        }

        // Reverse sort.
        // ... Can be looped over in the same way as above.
        items = from pair in dictionary
        orderby pair.Value descending
        select pair;
    }
}

产量 对象

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5

#2楼

您能够按值对Dictionary进行排序,并使用如下代码在字典中获取结果: 排序

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);

#3楼

使用LINQ: 索引

Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("one", 1);
myDict.Add("four", 4);
myDict.Add("two", 2);
myDict.Add("three", 3);

var sortedDict = from entry in myDict orderby entry.Value ascending select entry;

这也能够提供很大的灵活性,你能够选择前10个,20个10%等。或者若是你使用你的单词频率索引进行type-ahead ,你也能够包括StartsWith子句。 three


#4楼

您不对字典中的条目进行排序。 .NET中的字典类是做为哈希表实现的 - 根据定义,此数据结构不可排序。

若是您须要可以迭代您的集合(按键) - 您须要使用SortedDictionary,它实现为二进制搜索树。

在您的状况下,源结构是可有可无的,由于它按不一样的字段排序。 您仍然须要按频率对其进行排序,并将其放入按相关字段(频率)排序的新集合中。 因此在这个集合中,频率是键,单词是值。 因为许多单词能够具备相同的频率(而且您将其用做键),所以您既不能使用Dictionary也不能使用SortedDictionary(它们须要惟一键)。 这将为您提供SortedList。

我不明白为何你坚持维护主/第一本词典中原始项目的连接。

若是集合中的对象具备更复杂的结构(更多字段),而且您须要可以使用几个不一样的字段做为键来有效地访问/排序它们 - 您可能须要一个自定义数据结构,该结构将由主存储组成支持O(1)插入和删除(LinkedList)和几个索引结构--Dictionaries / SortedDictionaries / SortedLists。 这些索引将使用复杂类中的一个字段做为键,并将LinkedList中LinkedListNode的指针/引用用做值。

您须要协调插入和删除以使索引与主集合(LinkedList)保持同步,而且删除将是至关昂贵的我认为。 这与数据库索引的工做方式相似 - 它们很是适合查找,但当您须要执行许多限制和删除时,它们会成为负担。

若是您要进行一些查找重处理,上述全部内容都是合理的。 若是您只须要按频率排序就输出它们,那么您只需生成一个(匿名)元组列表:

var dict = new SortedDictionary<string, int>();
// ToDo: populate dict

var output = dict.OrderBy(e => e.Value).Select(e => new {frequency = e.Value, word = e.Key}).ToList();

foreach (var entry in output)
{
    Console.WriteLine("frequency:{0}, word: {1}",entry.frequency,entry.word);
}

#5楼

鉴于你有一本字典,你可使用下面的一个班轮直接对它们进行排序:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);