你如何按价值排序词典?

bnemo 发布于 2018-02-03 c# 最后更新 2018-02-03 01:05 473 浏览

我经常需要对字典进行排序,包括键和键。值,按价值。例如,我有一个单词和各自的频率散列,我想按频率排序。 有一个SortedList这是一个单一的值(比如说频率),我想把它映射回单词。 SortedDictionary按键排序,而不是值。有人诉诸custom class,但有没有更清晰的方法?

已邀请:

bnemo

赞同来自:

环顾四周,并使用一些C#3.0功能,我们可以做到这一点:

foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}
这是我见过的最干净的方式,类似于处理散列的Ruby方式。

mid

赞同来自:

在高层次上,你没有别的选择,然后遍历整个词典,看看每个价值。 也许这有助于: http://bytes.com/forum/thread563638.html 从John 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);
    }
);

taut

赞同来自:

使用:

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

wsint

赞同来自:

使用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;
如果您使用type-ahead的词频索引,那么也可以包含StartsWith子句。

tut

赞同来自:

无论如何,你永远无法排序字典。他们并没有实际订购。字典的保证是键和值集合是可迭代的,值可以通过索引或键来检索,但这里不保证任何特定的顺序。因此,您需要将名称值对变为列表。

faut

赞同来自:

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

wodio

赞同来自:

使用VB.NET对SortedDictionary列表进行排序以绑定到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>

rquis

赞同来自:

或者为了好玩,您可以使用一些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));

sut

赞同来自:

var ordered = dict.OrderBy(x => x.Value);

gautem

赞同来自:

您可以按值排序字典,并将其保存回自己(以便在对其进行遍历时,值依次出现):

dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
当然,这可能不是正确的,但它的工作。

ea_qui

赞同来自:

排序值 这显示如何排序词典中的值。我们看到一个控制台程序,您可以在Visual Studio中编译并运行。它将键添加到字典中,然后按值排序。请记住,字典实例最初并不以任何方式排序。我们在查询语句中使用LINQ orderby关键字。 OrderBy子句 程序排序字典[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

zrerum

赞同来自:

您可以按值对字典进行排序,并使用以下代码在字典中获取结果:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          

enemo

赞同来自:

您不要对词典中的条目进行排序。 .NET中的Dictionary类是作为散列表实现的 - 该数据结构不能按照定义进行排序。 如果您需要能够迭代您的集合(按键) - 您需要使用SortedDictionary,它是作为二进制搜索树实现的。 在你的情况下,然而源结构是不相关的,因为它是由不同的字段排序。您仍然需要按频率对其进行排序,并将其放入按相关字段(频率)排序的新集合中。所以在这个集合中,频率是关键字,单词是值。由于许多单词可能具有相同的频率(并且将要将其用作关键字),因此既不能使用Dictionary也不能使用SortedDictionary(它们需要唯一的键)。这给你一个SortedList。 我不明白你为什么坚持保持链接到你的主/第一字典中的原始项目。 如果集合中的对象具有更复杂的结构(更多的字段),并且您需要能够使用多个不同的字段作为键高效地访问/排序它们 - 您可能需要一个自定义的数据结构,支持O(1)插入和删除(LinkedList)以及多种索引结构 - Dictionaries/SortedDictionaries/SortedLists。这些索引将使用复杂类中的一个字段作为键,并将指向LinkedListNode的指针/引用作为值。 你将需要协调插入和删除,以保持您的索引与主集合(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);
}

svelit

赞同来自:

鉴于你有一本字典,你可以使用下面的一行来直接对它们进行排序:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);

eomnis

赞同来自:

假设我们有一本字典

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

iodit

赞同来自:

Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);

ket

赞同来自:

其他答案是好的,如果你想要的是有一个“临时”列表按价值排序。但是,如果希望按Key排序的字典按<Value>排序,<Bijection<K1, K2> class>与另一个按PLACEHOLDER_FOR_CODE_1排序的字典自动同步,则可以使用PLACEHOLDER_FOR_CODE_2。 Bijection<K1, K2>允许您使用两个现有字典初始化集合,所以如果您希望其中一个未排序,并且希望另一个排序,则可以使用代码创建双射

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());
您可以使用dict像任何常规词典(它实现IDictionary<>),然后调用dict.Inverse以获得按Value排序的“逆”字典。 Bijection<K1, K2>Loyc.Collections.dll的一部分,但是如果您愿意,您可以简单地将source code复制到您自己的项目中。 注意:如果有多个具有相同值的键,则不能使用Bijection,但可以在普通的Dictionary<Key,Value>BMultiMap<Value,Key>之间进行手动同步。