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

有一个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处理散列的方法。

其他回答

实际上在c#中,字典没有sort()方法。 如果你对按值排序更感兴趣, 在为值提供键之前,您无法获取值。 简而言之,你需要使用LINQ的OrderBy()迭代它们,

var items = new Dictionary<string, int>();
items.Add("cat", 0);
items.Add("dog", 20);
items.Add("bear", 100);
items.Add("lion", 50);

// Call OrderBy() method here on each item and provide them the IDs.
foreach (var item in items.OrderBy(k => k.Key))
{
    Console.WriteLine(item);// items are in sorted order
}

你可以做一个小技巧:

var sortedDictByOrder = items.OrderBy(v => v.Value);

or:

var sortedKeys = from pair in dictName
            orderby pair.Value ascending
            select pair;

这也取决于你存储的是什么类型的值:单个(如字符串,int)或多个(如列表,数组,用户定义的类)。 如果它是单个的,你可以把它列出来,然后应用排序。 如果它是用户定义的类,那么该类必须实现IComparable, ClassName: IComparable<ClassName>并覆盖compareTo(ClassName c),因为它们比LINQ更快,更面向对象。

获得一个排序字典最简单的方法是使用内置的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的排序版本

使用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子句。

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

使用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>