Как отсортировать словарь (Dictionary) по значению в C#?
Решение с помощью LINQ и метода OrderBy
Самый простой и распространённый способ — использовать LINQ (Language Integrated Query). Метод OrderBy позволяет отсортировать коллекцию по указанному ключу. В вашем случае ключом сортировки будет значение пары (Value).
Важно понимать: Dictionary не может быть отсортирован на месте, так как его внутренняя структура (хеш-таблица) не поддерживает порядок элементов. Поэтому мы создаём новую упорядоченную коллекцию, обычно это List или анонимный тип.
Вот полный пример кода:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "Alice", 85 },
{ "Bob", 92 },
{ "Charlie", 78 },
{ "Diana", 95 }
};
// Сортировка по значению (по возрастанию)
var sortedByValue = scores.OrderBy(pair => pair.Value);
Console.WriteLine("Студенты, отсортированные по баллам (возрастание):");
foreach (var pair in sortedByValue)
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
// Если нужна сортировка по убыванию, используем OrderByDescending
var sortedDescending = scores.OrderByDescending(pair => pair.Value);
Console.WriteLine("\nСтуденты, отсортированные по баллам (убывание):");
foreach (var pair in sortedDescending)
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
}
}
Как это работает?
scores.OrderBy(pair => pair.Value)— берёт каждую пару из словаря и сортирует их по свойствуValue.- Результат — объект типа
IOrderedEnumerable<KeyValuePair<string, int>>, который можно перебирать в циклеforeach. - Сам словарь
scoresостаётся неизменным.
Сохранение результата в список
Если вам нужно не только вывести данные, но и сохранить их для дальнейшей работы, преобразуйте результат в список:
List<KeyValuePair<string, int>> sortedList = scores.OrderBy(pair => pair.Value).ToList();
Сортировка по нескольким критериям
Если значения одинаковы, можно добавить вторичную сортировку по ключу:
var sorted = scores.OrderBy(pair => pair.Value).ThenBy(pair => pair.Key);
Важные замечания
- Не забудьте добавить
using System.Linq;в начало файла. - Метод
OrderByвозвращает новую коллекцию, исходный словарь не изменяется. - Для обратного порядка используйте
OrderByDescending.
Этот подход работает во всех версиях .NET Framework и .NET Core/.NET 5+. Он лаконичен, читаем и использует мощь LINQ.
<<Альтернативный подход: использование SortedDictionary с кастомным компаратором
Если вам нужно, чтобы словарь всегда оставался отсортированным по значению (а не только при выводе), можно использовать SortedDictionary с собственным компаратором. Однако это сложнее, так как SortedDictionary сортирует по ключу, а не по значению. Придётся создать класс-обёртку.
Вот пример для случая, когда значения уникальны:
public class ValueComparer : IComparer<int>
{
public int Compare(int x, int y) => x.CompareTo(y);
}
// Использование:
var sortedByValue = new SortedDictionary<int, string>();
foreach (var pair in scores)
{
sortedByValue[pair.Value] = pair.Key; // Меняем местами ключ и значение
}
// Теперь sortedByValue отсортирован по ключу (бывшему значению)
Недостатки:
- Значения должны быть уникальными, иначе произойдёт перезапись.
- Код менее читаем и более громоздок.
Поэтому для большинства задач рекомендуется первый способ с LINQ. Он проще и гибче.