你如何按价值sorting词典?
我经常不得不按照价值来整理由键和值组成的字典。 例如,我有一个单词和各自的频率散列,我想按频率sorting。
有一个SortedList
对单个值(比如说频率)很有用,我想把它映射回单词。
SortedDictionary按键sorting ,不是值。 有人诉诸自定义课程 ,但有一个更清洁的方式?
使用:
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;
这也可以提供很大的灵活性,你可以select前10,20 10%等。或者,如果你正在使用你的单词频率索引type-ahead
,也可以包含StartsWith
子句。
var ordered = dict.OrderBy(x => x.Value);
环顾四周,并使用一些C#3.0function,我们可以做到这一点:
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value)) { // do something with item.Key and item.Value }
这是我见过的最干净的方式,类似于处理散列的Ruby方式。
您可以按值sorting字典,并将其保存回自己(以便在对其进行遍历时,值依次出现):
dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
当然,这可能不是正确的,但它的工作。
在高层次上,你没有别的select,然后遍历整个词典,看看每个价值。
也许这有助于: http : //bytes.com/forum/thread563638.html复制/粘贴从约翰·Timney:
Dictionary<string, string> s = new Dictionary<string, string>(); s.Add("1", "a Item"); s.Add("2", "c Item"); s.Add("3", "b Item"); List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s); myList.Sort( delegate(KeyValuePair<string, string> firstPair, KeyValuePair<string, string> nextPair) { return firstPair.Value.CompareTo(nextPair.Value); } );
无论如何,你永远无法sorting字典。 他们并没有实际订购。 字典的保证是键和值集合是可迭代的,值可以通过索引或键来检索,但这里不保证任何特定的顺序。 因此,您需要将名称值对变为列表。
您不要对词典中的条目进行sorting。 .NET中的Dictionary类是作为散列表实现的 – 该数据结构不能按照定义进行sorting。
如果您需要能够迭代您的集合(按键) – 您需要使用SortedDictionary,它是作为二进制search树实现的。
在你的情况下,然而源结构是不相关的,因为它是由不同的字段sorting。 您仍然需要按频率对其进行sorting,并将其放入按相关字段(频率)sorting的新集合中。 所以在这个集合中,频率是关键字,单词是值。 由于许多单词可能具有相同的频率(并且将要将其用作关键字),因此既不能使用Dictionary也不能使用SortedDictionary(它们需要唯一的键)。 这给你一个SortedList。
我不明白你为什么坚持保持链接到你的主/第一字典中的原始项目。
如果集合中的对象具有更复杂的结构(更多的字段),并且您需要能够使用多个不同的字段作为键高效地访问/sorting它们 – 您可能需要一个自定义的数据结构,支持O(1)插入和删除(LinkedList)以及多种索引结构 – Dictionaries / SortedDictionaries / SortedLists。 这些索引将使用复杂类中的一个字段作为键,并将指向LinkedListNode的指针/引用作为值。
你将需要协调插入和删除,以保持您的索引与主集合(LinkedList)同步,删除将是相当昂贵,我想。 这与数据库索引的工作方式类似 – 它们对于查找来说非常棒,但当您需要执行许多删除和删除操作时,它们将成为一种负担。
以上所有内容只有在您要查找大量的处理时才是正确的。 如果你只需要输出一次按频率sorting,那么你可以产生(匿名)元组的列表:
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); }
或者为了好玩,您可以使用一些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));
sorting值
这显示如何sorting词典中的值。 我们看到一个控制台程序,您可以在Visual Studio中编译并运行。 它将键添加到字典中,然后按值sorting。 请记住,字典实例最初并不以任何方式sorting。 我们在查询语句中使用LINQ orderby关键字。
OrderBy子句sorting字典[C#]
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { // Example dictionary. var dictionary = new Dictionary<string, int>(5); dictionary.Add("cat", 1); dictionary.Add("dog", 0); dictionary.Add("mouse", 5); dictionary.Add("eel", 3); dictionary.Add("programmer", 2); // Order by values. // ... Use LINQ to specify sorting by value. var items = from pair in dictionary orderby pair.Value ascending select pair; // Display results. foreach (KeyValuePair<string, int> pair in items) { Console.WriteLine("{0}: {1}", pair.Key, pair.Value); } // Reverse sort. // ... Can be looped over in the same way as above. items = from pair in dictionary orderby pair.Value descending select pair; } }
产量
dog: 0 cat: 1 programmer: 2 eel: 3 mouse: 5
Dictionary<string, string> dic= new Dictionary<string, string>(); var ordered = dic.OrderBy(x => x.Value); return ordered.ToDictionary(t => t.Key, t => t.Value);
对SortedDictionary
列表进行sorting以使用VB.NET绑定到ListView
控件中:
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>
获取sorting字典最简单的方法是使用内置的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
将包含节的sorting版本
其他答案是好的,如果你想要的是有一个“临时”列表按价值sorting。 但是,如果您希望按照Key
sorting的字典能够自动与按Value
sorting的另一个字典进行同步 ,则可以使用Bijection<K1, K2>
类 。
Bijection<K1, K2>
允许你用两个现有的字典来初始化集合,所以如果你想让其中的一个没有sorting,并且你希望另一个被sorting,你可以使用代码
var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), new SortedDictionary<Value,Key>());
你可以像任何普通字典一样使用字典(它实现了IDictionary<>
),然后调用dict.Inverse
得到按Value
sorting的“inverse”字典。
Bijection<K1, K2>
是Loyc.Collections.dll的一部分,但是如果你愿意,你可以简单地将源代码复制到你自己的项目中。
注意 :如果有多个具有相同值的键,则不能使用Bijection
,但可以在普通Dictionary<Key,Value>
和BMultiMap<Value,Key>
之间手动同步。
假设我们有一本字典
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); sict.Add(768, 1011);
1)你可以使用temporary dictionary to store values as
:
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); }
您可以按值对字典进行sorting,并使用以下代码在字典中获取结果:
Dictionary <<string, string>> ShareUserNewCopy = ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key, pair => pair.Value);
鉴于你有一本字典,你可以使用下面的一行来直接对它们进行sorting:
var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);