Мне часто приходится сортировать словарь, состоящий из ключей и значений, по значению. Например, у меня есть хэш слов и соответствующих частот, которые я хочу упорядочить по частоте.
Существует вариант, SortedList
который подходит для одного значения (скажем, частоты), и я хочу сопоставить его со словом.
SortedDictionary заказывает по ключу, а не по значению. Некоторые прибегают к пользовательскому классу , но есть ли более чистый способ?
c#
.net
sorting
dictionary
Kalid
источник
источник
IComparer
которая делает трюк (правда, она принимает ключ для сравнения, но с помощью ключа вы можете получить значение). ;-)Ответы:
Использование:
Поскольку вы ориентируетесь на .NET 2.0 или выше, вы можете упростить это до лямбда-синтаксиса - он эквивалентен, но короче. Если вы ориентируетесь на .NET 2.0, вы можете использовать этот синтаксис, только если вы используете компилятор из Visual Studio 2008 (или выше).
источник
myList.Sort((x,y)=>x.Value.CompareTo(y.Value));
IEnumerable
, так что вы можете получить отсортированный список, подобный этому:var mySortedList = myDictionary.OrderBy(d => d.Value).ToList();
Используйте LINQ:
Это также обеспечит большую гибкость в том, что вы можете выбрать верхние 10, 20, 10% и т. Д. Или, если вы используете свой индекс частоты слов для
type-ahead
, вы также можете включитьStartsWith
предложение.источник
IEnumerable<KeyValuePair<TKey, TValue>>
илиOrderedDictionary<TKey, TValue>
. Или следует использоватьSortedDictionary
с самого начала. Для простогоDictionary
MSDN ясно заявляет, что "порядок, в котором возвращаются элементы, не определен". Похоже, что последняя редакция @ rythos42 виновата. :).ToDictionary
источник
Оглядываясь вокруг, и используя некоторые функции C # 3.0, мы можем сделать это:
Это самый чистый способ, который я видел, и он похож на способ обработки хэшей в Ruby.
источник
(for KeyValuePair<string, int> item in keywordCounts.OrderBy(key => key.Value) select item).ToDictionary(t => t.Key, t => t.Value)
- просто небольшое дополнение к вашему ответу :) Спасибо, кстати :)Вы можете отсортировать словарь по значению и сохранить его обратно в себе (так что, когда вы просматриваете его, значения выводятся по порядку):
Конечно, это может быть не правильно, но это работает.
источник
На высоком уровне у вас нет другого выбора, кроме как пройти весь словарь и посмотреть на каждое значение.
Может быть, это поможет: http://bytes.com/forum/thread563638.html Копирование / вставка от Джона Тимни:
источник
Вы никогда не сможете отсортировать словарь в любом случае. Они на самом деле не заказаны. Гарантии для словаря состоят в том, что наборы ключей и значений являются итеративными, а значения могут быть получены по индексу или ключу, но нет гарантии какого-либо конкретного порядка. Следовательно, вам нужно получить пару имя-значение в список.
источник
Вы не сортируете записи в Словаре. Класс словаря в .NET реализован как хеш-таблица - эта структура данных не сортируется по определению.
Если вам нужно иметь возможность перебирать свою коллекцию (по ключу) - вам нужно использовать SortedDictionary, который реализован в виде дерева двоичного поиска.
В вашем случае, однако, структура источника не имеет значения, потому что она сортируется по другому полю. Вам все равно нужно отсортировать его по частоте и поместить в новую коллекцию, отсортированную по соответствующему полю (частоте). Таким образом, в этой коллекции частоты являются ключами, а слова - значениями. Поскольку многие слова могут иметь одинаковую частоту (и вы собираетесь использовать его в качестве ключа), вы не можете использовать ни Dictionary, ни SortedDictionary (для них требуются уникальные ключи). Это оставляет вас с SortedList.
Я не понимаю, почему вы настаиваете на сохранении ссылки на оригинальный элемент в вашем основном / первом словаре.
Если объекты в вашей коллекции имеют более сложную структуру (больше полей) и вам необходимо иметь возможность эффективно обращаться к ним / сортировать их, используя несколько различных полей в качестве ключей - вам, вероятно, понадобится настраиваемая структура данных, которая будет состоять из основного хранилища, которое поддерживает вставку и удаление O (1) (LinkedList) и несколько структур индексации - Словари / SortedDictionaries / SortedLists. Эти индексы будут использовать одно из полей вашего сложного класса в качестве ключа и указатель / ссылку на LinkedListNode в LinkedList в качестве значения.
Вам нужно было бы координировать вставки и удаления, чтобы синхронизировать ваши индексы с основной коллекцией (LinkedList), и удаления, я думаю, будет довольно дорогим. Это похоже на работу индексов базы данных - они отлично подходят для поиска, но становятся бременем, когда вам нужно выполнить много вставок и удалений.
Все вышеперечисленное оправдано только в том случае, если вы собираетесь выполнить некоторую сложную обработку. Если вам нужно вывести их только один раз по частоте, вы можете просто создать список (анонимных) кортежей:
источник
источник
Или для удовольствия вы можете использовать некоторые расширения LINQ:
источник
Сортировка
SortedDictionary
списка для привязки к элементуListView
управления с использованием VB.NET:XAML:
источник
Самый простой способ получить отсортированный словарь - использовать встроенный
SortedDictionary
класс:sortedSections
будет содержит отсортированную версиюsections
источник
SortedDictionary
сортировка по ключам. ОП хочет отсортировать по значению.SortedDictionary
не помогает в этом случае.sorteddictionary()
всегда выигрывал, по крайней мере, на 1 микросекунду, и им намного легче управлять (поскольку издержки преобразования его обратно во что-то, с чем легко взаимодействовать и управлять им, как в словаре, равны 0 (это уже asorteddictionary
)).Другие ответы хороши, если все, что вам нужно, это иметь «временный» список, отсортированный по значению. Однако, если вы хотите, чтобы словарь, отсортированный по ним
Key
, автоматически синхронизировался с другим словарем, который сортируетсяValue
, вы можете использоватьBijection<K1, K2>
класс .Bijection<K1, K2>
позволяет инициализировать коллекцию двумя существующими словарями, поэтому, если вы хотите, чтобы один из них не был отсортирован, а другой - отсортирован, вы можете создать свою биекцию с кодом, подобнымВы можете использовать
dict
как любой обычный словарь (он реализуетIDictionary<K, V>
), а затем вызывать,dict.Inverse
чтобы получить «обратный» словарь, который сортируется поValue
.Bijection<K1, K2>
является частью Loyc.Collections.dll , но если вы хотите, вы можете просто скопировать исходный код в ваш собственный проект.Примечание . Если имеется несколько ключей с одинаковым значением, вы не можете их использовать
Bijection
, но вы можете вручную синхронизировать обычноеDictionary<Key,Value>
и aBMultiMap<Value,Key>
.источник
Предположим, у нас есть словарь
1) вы можете использовать
temporary dictionary to store values as
:источник
На самом деле в C # словари dint имеют методы sort (), так как вас больше интересует сортировка по значениям, вы не можете получать значения до тех пор, пока не предоставите их ключ, короче говоря, вам нужно перебирать их, используя LINQ Order By,
ты можешь сделать один трюк,
или
Он также зависит от того, какие значения вы храните
: одиночные (например, string, int) или множественные (например, List, Array, пользовательский класс),
если вы можете создать один из них, то примените сортировку.
если пользовательский класс, то этот класс должен реализовывать IComparable
ClassName: IComparable<ClassName>
и переопределять, такcompareTo(ClassName c)
как они быстрее, чем LINQ, и более объектно-ориентированы.источник
Обязательное пространство имен:
using System.Linq;
Сортировать по desc:
Заказ по Asc:
источник
Вы можете отсортировать словарь по значению и получить результат в словаре, используя код ниже:
источник
Учитывая, что у вас есть словарь, вы можете отсортировать их по значениям, используя ниже один слой:
источник