我经常需要按值排序字典,包括键和值 . 例如,我有一个单词的散列和各自的频率,我想按频率排序 .
有一个 SortedList
,它适用于单个值(比如频率),我想将它映射回单词 .
SortedDictionary按键排序,而不是值 . 有些人诉诸custom class,但有更清洁的方式吗?
我经常需要按值排序字典,包括键和值 . 例如,我有一个单词的散列和各自的频率,我想按频率排序 .
有一个 SortedList
,它适用于单个值(比如频率),我想将它映射回单词 .
SortedDictionary按键排序,而不是值 . 有些人诉诸custom class,但有更清洁的方式吗?
17 回答
您不对“词典”中的条目进行排序 . .NET中的字典类是作为哈希表实现的 - 根据定义,此数据结构不可排序 .
如果您需要能够迭代您的集合(按键) - 您需要使用SortedDictionary,它实现为二进制搜索树 .
在您的情况下,源结构是无关紧要的,因为它按不同的字段排序 . 您仍然需要按频率对其进行排序,并将其放入按相关字段(频率)排序的新集合中 . 所以在这个集合中,频率是键,单词是值 . 由于许多单词可以具有相同的频率(并且您将其用作键),因此您既不能使用Dictionary也不能使用SortedDictionary(它们需要唯一的键) . 这将为您提供SortedList .
我不明白为什么你坚持要维护主/第一本词典中原始项目的链接 .
如果集合中的对象具有更复杂的结构(更多字段),并且您需要能够使用几个不同的字段作为键来有效地访问/排序它们 - 您可能需要一个自定义数据结构,该结构将由主存储组成支持O(1)插入和删除(LinkedList)和几个索引结构--Dictionaries / SortedDictionaries / SortedLists . 这些索引将使用复杂类中的一个字段作为键,并将LinkedList中LinkedListNode的指针/引用用作值 .
您需要协调插入和删除以使索引与主集合(LinkedList)保持同步,并且删除将非常昂贵我认为 . 这与数据库索引的工作方式类似 - 它们非常适合查找,但当您需要执行许多限制和删除时,它们会成为负担 .
如果您要进行一些查找重处理,上述所有内容都是合理的 . 如果您只需要按频率排序就输出它们,那么您只需生成一个(匿名)元组列表:
获取已排序字典的最简单方法是使用内置的
SortedDictionary
类:sortedSections
将包含sections
的排序版本使用LINQ:
这也可以提供很大的灵活性,你可以选择前10个,20个10%等 . 或者如果你使用
type-ahead
的单词频率索引,你也可以包含StartsWith
子句 .您可以按值对字典进行排序并将其保存回自身(这样当您对其进行预处理时,值将按顺序排出):
当然,它可能不正确,但它确实有效 .
环顾四周,并使用一些C#3.0功能,我们可以这样做:
这是我见过的最干净的方式,类似于Ruby处理哈希的方式 .
在较高的层面上,您没有其他选择可以遍历整个字典并查看每个值 .
也许这会有所帮助:http://bytes.com/forum/thread563638.html从John Timney复制/粘贴:
使用VB.NET对
SortedDictionary
列表进行排序以绑定到ListView
控件:XAML:
您可以按值对Dictionary进行排序,并使用以下代码在字典中获取结果:
假设我们有一本字典
1)你可以使用 temporary dictionary to store values as :
排序值
这显示了如何对Dictionary中的值进行排序 . 我们看到一个可以在Visual Studio中编译并运行的控制台程序 . 它为Dictionary添加键,然后按其值对它们进行排序 . 请记住,Dictionary实例最初不以任何方式排序 . 我们在查询语句中使用LINQ orderby关键字 .
对字典[C#]进行排序的OrderBy子句程序
产量
或者为了好玩,你可以使用一些LINQ扩展优点:
使用:
由于您的目标是.NET 2.0或更高版本,因此您可以将其简化为lambda语法 - 它等效,但更短 . 如果您的目标是.NET 2.0,那么只有在使用Visual Studio 2008(或更高版本)的编译器时才能使用此语法 .
其他答案都很好,如果您想要的是按值排序"temporary"列表 . 但是,如果您希望按
Key
排序的字典自动与Value
排序的另一个字典同步,则可以使用Bijection<K1, K2> class .Bijection<K1, K2>
允许您使用两个现有字典初始化集合,因此如果您希望其中一个字典未排序,并且您希望对另一个字典进行排序,则可以使用代码创建您的双射喜欢您可以像任何普通字典一样使用
dict
(它实现IDictionary<K, V>
),然后调用dict.Inverse
来获取"inverse"字典,该字典按Value
排序 .Bijection<K1, K2>
是Loyc.Collections.dll的一部分,但如果您愿意,您只需将source code复制到您自己的项目中即可 .Note :如果有多个键具有相同的值,则不能使用
Bijection
,但可以在普通Dictionary<Key,Value>
和BMultiMap<Value,Key>之间手动同步 .无论如何,你永远无法对字典进行排序 . 他们实际上没有订购 . 字典的保证是键和值集合是可迭代的,并且值可以通过索引或键来检索,但这里不保证任何特定的顺序 . 因此,您需要将名称值对放入列表中 .
鉴于您有一本字典,您可以使用下面的一个班轮直接对它们进行排序: