Как вы сортируете словарь по значению?
523661 просмотра
18 ответа
Мне часто приходится сортировать словарь, состоящий из ключей и значений, по значению. Например, у меня есть хэш слов и соответствующих частот, которые я хочу упорядочить по частоте.
Существует вариант, SortedList
который подходит для одного значения (скажем, частоты), и я хочу сопоставить его со словом.
SortedDictionary заказывает по ключу, а не по значению. Некоторые прибегают к пользовательскому классу , но есть ли более чистый способ?
Автор: Kalid Источник Размещён: 17.05.2019 02:58Ответы (18)
491 плюса
Использование:
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 или выше, вы можете упростить это до лямбда-синтаксиса - это эквивалентно, но короче. Если вы ориентируетесь на .NET 2.0, вы можете использовать этот синтаксис, только если вы используете компилятор из Visual Studio 2008 (или выше).
var myList = aDictionary.ToList();
myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Автор: Leon Bambrick
Размещён: 02.08.2008 01:15
495 плюса
Используйте 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;
Это также обеспечит большую гибкость в том, что вы можете выбрать верхние 10, 20, 10% и т. Д. Или, если вы используете свой индекс частоты слов для type-ahead
, вы также можете включить StartsWith
предложение.
201 плюса
157 плюса
Оглядываясь вокруг и используя некоторые функции C # 3.0, мы можем сделать это:
foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{
// do something with item.Key and item.Value
}
Это самый чистый способ, который я видел, и он похож на способ обработки хэшей в Ruby.
Автор: Kalid Размещён: 02.08.2008 12:43147 плюса
Вы можете отсортировать словарь по значению и сохранить его обратно в себе (чтобы при нахождении над ним значения располагались по порядку):
dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
Конечно, это может быть не правильно, но это работает.
Автор: Matt Frear Размещён: 22.06.2011 10:2659 плюса
На высоком уровне у вас нет другого выбора, кроме как пройти весь словарь и посмотреть на каждое значение.
Может быть, это поможет: http://bytes.com/forum/thread563638.html Копирование / вставка от Джона Тимни:
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);
}
);
Автор: Michael Stum
Размещён: 02.08.2008 12:47
23 плюса
Вы никогда не сможете отсортировать словарь в любом случае. Они на самом деле не заказаны. Гарантии для словаря состоят в том, что наборы ключей и значений являются итеративными, и значения могут быть получены по индексу или ключу, но здесь нет гарантии какого-либо конкретного порядка. Следовательно, вам нужно получить пару имя-значение в список.
Автор: Roger Willcocks Размещён: 19.12.2008 10:4716 плюса
Вы не сортируете записи в Словаре. Класс словаря в .NET реализован как хеш-таблица - эта структура данных не сортируется по определению.
Если вам нужно иметь возможность перебирать свою коллекцию (по ключу) - вам нужно использовать SortedDictionary, который реализован в виде дерева двоичного поиска.
В вашем случае, однако, структура источника не имеет значения, потому что она сортируется по другому полю. Вам все равно нужно отсортировать его по частоте и поместить в новую коллекцию, отсортированную по соответствующему полю (частоте). Таким образом, в этой коллекции частоты являются ключами, а слова - значениями. Поскольку многие слова могут иметь одинаковую частоту (и вы собираетесь использовать его в качестве ключа), вы не можете использовать ни Dictionary, ни SortedDictionary (для них требуются уникальные ключи). Это оставляет вас с SortedList.
Я не понимаю, почему вы настаиваете на сохранении ссылки на оригинальный элемент в вашем основном / первом словаре.
Если объекты в вашей коллекции имеют более сложную структуру (больше полей) и вам необходимо иметь возможность эффективно обращаться к ним / сортировать их, используя несколько различных полей в качестве ключей - вам, вероятно, понадобится настраиваемая структура данных, которая будет состоять из основного хранилища, которое поддерживает вставку и удаление O (1) (LinkedList) и несколько структур индексирования - Dictionaries / SortedDictionaries / SortedLists. Эти индексы будут использовать одно из полей вашего сложного класса в качестве ключа и указатель / ссылку на LinkedListNode в LinkedList в качестве значения.
Вам нужно было бы координировать вставки и удаления, чтобы синхронизировать ваши индексы с основной коллекцией (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);
}
Автор: Zar Shardan
Размещён: 13.12.2012 06:19
13 плюса
Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Автор: mrfazolka
Размещён: 20.07.2015 11:01
10 плюса
Или для удовольствия вы можете использовать некоторые расширения 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));
Автор: mythz
Размещён: 30.06.2010 11:12
10 плюса
Сортировать значения
Это показывает, как сортировать значения в словаре. Мы видим консольную программу, которую вы можете скомпилировать в Visual Studio и запустить. Он добавляет ключи в словарь, а затем сортирует их по их значениям. Помните, что экземпляры словаря изначально никак не сортируются. Мы используем ключевое слово LINQ orderby в запросе.
OrderBy Clause Программа, которая сортирует словарь [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
Автор: lasitha edirisooriya
Размещён: 20.07.2012 09:49
9 плюса
Сортировка 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>
Автор: BSalita
Размещён: 23.04.2010 09:36
5 плюса
Самый простой способ получить отсортированный словарь - использовать встроенный 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
5 плюса
Другие ответы хороши, если все, что вам нужно, это иметь «временный» список, отсортированный по значению. Однако, если вы хотите, чтобы словарь, отсортированный по ним 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>
и a BMultiMap<Value,Key>
.
3 плюса
Предположим, у нас есть словарь
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);
}
Автор: Akshay Kapoor
Размещён: 02.02.2015 10:46
0 плюса
На самом деле в 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);
Он также зависит от того, какие значения вы сохраняете
: одиночные (например, string, int) или множественные (например, List, Array),
если вы можете создать единый список, то примените sort.
-2 плюса
Вы можете отсортировать словарь по значению и получить результат в словаре, используя код ниже:
Dictionary <<string, string>> ShareUserNewCopy =
ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
pair => pair.Value);
Автор: pawan Kumar
Размещён: 24.07.2012 12:24
-2 плюса
Учитывая, что у вас есть словарь, вы можете сортировать их по значениям, используя ниже одну строку:
var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Автор: aggaton
Размещён: 31.05.2014 10:30
Вопросы из категории :
- c# Преобразовать десятичную в двойную?
- c# Как рассчитать чей-то возраст в C #?
- c# Как вы сортируете словарь по значению?
- c# В чем разница между int и Integer в Java и C #?
- c# Как создать новый экземпляр объекта из Типа
- .net Действительно ли опечатанные классы действительно предлагают преимущества?
- .net Setting Objects to Null/Nothing after use in .NET
- sorting Объединить Сортировать связанный список
- sorting Natural (human alpha-numeric) sort in Microsoft SQL 2005
- sorting Как отсортировать список строк?
- sorting Как отсортировать список словарей по значению словаря?
- dictionary Как объединить два словаря в одном выражении?
- dictionary Как эффективно перебирать каждую запись на карте Java?
- dictionary Sort a Map<Key, Value> by values