我经常需要根据值对字典(由键和值组成)进行排序。例如,我有一个单词和相应频率的散列,我想按频率排序。

有一个SortedList,它适用于单个值(比如频率),我想把它映射回单词。

SortedDictionary按键排序,而不是按值。有些人求助于自定义课程,但有没有更干净的方法呢?


当前回答

环顾四周,使用一些c# 3.0特性,我们可以这样做:

foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

这是我见过的最干净的方法,类似于Ruby处理散列的方法。

其他回答

你可以按值对Dictionary进行排序,并使用下面的代码在Dictionary中获取结果:

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

如果您想要的只是一个按值排序的“临时”列表,那么其他答案都很好。然而,如果你想让一个按Key排序的字典自动与另一个按Value排序的字典同步,你可以使用Bijection<K1, K2>类。

双射<K1, K2>允许您使用两个现有字典初始化集合,因此如果您希望其中一个字典是无序的,而另一个字典是有序的,您可以使用如下代码创建双射

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

您可以像使用任何普通字典一样使用dict(它实现了dicictionary <K, V>),然后调用dict。以获得“逆”字典,它是由值排序。

Bijection<K1, K2>是Loyc.Collections.dll的一部分,但如果您愿意,您可以简单地将源代码复制到您自己的项目中。

注意:如果有多个键具有相同的值,您不能使用双射,但您可以手动同步普通Dictionary<Key, value >和BMultiMap< value, Key>。

Use:

using System.Linq.Enumerable;
...
List<KeyValuePair<string, string>> myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair<string, string> pair1,
    KeyValuePair<string, string> pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

由于您的目标是。net 2.0或更高版本,因此可以将其简化为lambda语法——它是等效的,但更简短。如果你的目标是。net 2.0,你只能在使用Visual Studio 2008(或更高版本)的编译器时使用这个语法。

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));

使用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%等等。或者,如果您正在使用词频索引进行提前输入,您还可以包括StartsWith子句。

你可以用:

var ordered = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);