我经常需要根据值对字典(由键和值组成)进行排序。例如,我有一个单词和相应频率的散列,我想按频率排序。
有一个SortedList,它适用于单个值(比如频率),我想把它映射回单词。
SortedDictionary按键排序,而不是按值。有些人求助于自定义课程,但有没有更干净的方法呢?
我经常需要根据值对字典(由键和值组成)进行排序。例如,我有一个单词和相应频率的散列,我想按频率排序。
有一个SortedList,它适用于单个值(比如频率),我想把它映射回单词。
SortedDictionary按键排序,而不是按值。有些人求助于自定义课程,但有没有更干净的方法呢?
当前回答
分类打印:
var items = from pair in players_Dic
orderby pair.Value descending
select pair;
// Display results.
foreach (KeyValuePair<string, int> pair in items)
{
Debug.Log(pair.Key + " - " + pair.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));
获得一个排序字典最简单的方法是使用内置的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的排序版本
使用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>
假设我们有一个这样的字典:
Dictionary<int, int> dict = new Dictionary<int, int>();
dict.Add(21,1041);
dict.Add(213, 1021);
dict.Add(45, 1081);
dict.Add(54, 1091);
dict.Add(3425, 1061);
dict.Add(768, 1011);
你可以使用临时字典来存储值:
Dictionary<int, int> dctTemp = new Dictionary<int, int>();
foreach (KeyValuePair<int, int> pair in dict.OrderBy(key => key.Value))
{
dctTemp.Add(pair.Key, pair.Value);
}
您不需要对Dictionary中的条目进行排序。. net中的Dictionary类是作为哈希表实现的——这个数据结构在定义上是不可排序的。
如果你需要能够遍历你的集合(按键)-你需要使用SortedDictionary,它被实现为二叉搜索树。
然而,在您的例子中,源结构是不相关的,因为它是根据不同的字段排序的。您仍然需要按频率对其进行排序,并将其放入按相关字段(频率)排序的新集合中。在这个集合中,频率是键,单词是值。由于许多单词可以具有相同的频率(并且您将使用它作为键),因此不能既使用Dictionary也使用SortedDictionary(它们需要惟一的键)。这将留给您一个SortedList。
我不明白为什么你坚持在你的主/第一个字典中保持一个到原始条目的链接。
If the objects in your collection had a more complex structure (more fields) and you needed to be able to efficiently access/sort them using several different fields as keys - You would probably need a custom data structure that would consist of the main storage that supports O(1) insertion and removal (LinkedList) and several indexing structures - Dictionaries/SortedDictionaries/SortedLists. These indexes would use one of the fields from your complex class as a key and a pointer/reference to the LinkedListNode in the LinkedList as a value.
你需要协调插入和删除,以保持你的索引与主集合(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);
}