Как вы сортируете словарь по значению? - PullRequest
742 голосов
/ 02 августа 2008

Мне часто приходится сортировать словарь, состоящий из ключей и значений, по значению. Например, у меня есть хэш слов и соответствующих частот, которые я хочу упорядочить по частоте.

Существует SortedList, который подходит для одного значения (скажем, частоты), и я хочу сопоставить его со словом.

SortedDictionary заказы по ключу, а не по значению. Некоторые прибегают к пользовательскому классу , но есть ли более чистый способ?

Ответы [ 18 ]

10 голосов
/ 30 июня 2010

Или для развлечения вы можете использовать некоторые расширения 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));
9 голосов
/ 23 апреля 2010

Сортировка списка SortedDictionary для привязки к элементу управления ListView с использованием VB.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>
5 голосов
/ 26 февраля 2016

Другие ответы хороши, если все, что вам нужно, это иметь «временный» список, отсортированный по значению. Однако, если вы хотите, чтобы словарь был отсортирован по Key, который автоматически синхронизирует с другим словарем, отсортированным по Value, вы можете использовать Bijection<K1, K2> класс .

Bijection<K1, K2> позволяет инициализировать коллекцию с двумя существующими словарями, поэтому, если вы хотите, чтобы один из них не был отсортирован, а другой сортировался, вы можете создать свою биекцию с кодом, подобным

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

Вы можете использовать dict как любой обычный словарь (он реализует IDictionary<K, V>), а затем вызвать dict.Inverse, чтобы получить «обратный» словарь, который отсортирован по Value.

Bijection<K1, K2> является частью Loyc.Collections.dll , но при желании вы можете просто скопировать исходный код в свой собственный проект.

Примечание : если несколько ключей с одинаковым значением, вы не можете использовать Bijection, но вы можете вручную синхронизировать между обычными Dictionary<Key,Value> и BMultiMap<Value,Key> .

5 голосов
/ 03 апреля 2010

Самый простой способ получить отсортированный словарь - использовать встроенный класс 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

3 голосов
/ 02 февраля 2015

Предположим, у нас есть словарь как

   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);
        }
0 голосов
/ 26 февраля 2019

На самом деле в C # словари dint имеют методы sort (), как вы больше заинтересованы в сортировке по значениям, вы не можете получить значения, пока не предоставите им ключ, Короче говоря, вам нужно перебирать их, используя LINQ Order By,

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

или

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

также зависит от того, какие значения вы храните,
это один (например, строка, int) или несколько (например, список, массив, пользовательский класс),
если вы одиноки, вы можете составить список, а затем применить сортировку.
если пользовательский класс, тогда этот класс должен реализовывать IComparable,
ClassName: IComparable<ClassName> и переопределить compareTo(ClassName c) так как они быстрее, чем LINQ, и более объектно-ориентированы.

0 голосов
/ 01 июня 2014

Учитывая, что у вас есть словарь, вы можете сортировать их по значениям, используя ниже один слой:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
0 голосов
/ 24 июля 2012

Вы можете отсортировать словарь по значению и получить результат в словаре, используя следующий код:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...