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

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

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


当前回答

如果您想要的只是一个按值排序的“临时”列表,那么其他答案都很好。然而,如果你想让一个按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>。

其他回答

或者为了好玩,你可以使用一些LINQ扩展的优点:

var dictionary = new Dictionary<string, int> { { "c", 3 }, { "a", 1 }, { "b", 2 } };
dictionary.OrderBy(x => x.Value)
  .ForEach(x => Console.WriteLine("{0}={1}", x.Key,x.Value));

使用VB对SortedDictionary列表进行排序以绑定到ListView控件。NET:

Dim MyDictionary As SortedDictionary(Of String, MyDictionaryEntry)

MyDictionaryListView.ItemsSource = MyDictionary.Values.OrderByDescending(Function(entry) entry.MyValue)

Public Class MyDictionaryEntry ' Need Property for GridViewColumn DisplayMemberBinding
    Public Property MyString As String
    Public Property MyValue As Integer
End Class

XAML:

<ListView Name="MyDictionaryListView">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyString}" Header="MyStringColumnName"></GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyValue}" Header="MyValueColumnName"></GridViewColumn>
         </GridView>
    </ListView.View>
</ListView>

获得一个排序字典最简单的方法是使用内置的SortedDictionary类:

//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary<int, string> sortedSections = null;
if (sections != null)
{
    sortedSections = new SortedDictionary<int, string>(sections);
}

sortedSections将包含section的排序版本

最好的方法:

var list = dict.Values.OrderByDescending(x => x).ToList();
var sortedData = dict.OrderBy(x => list.IndexOf(x.Value));

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));