Полное руководство по языку программирования С# 14 и платформе .NET 10 / LINQ

Сортировка

Начальный ⏱ 4 мин чтения 👁 2 🕓 обновлено 11.08.2026

Оператор orderby и метод OrderBy

Для сортировки набора данных в LINQ можно применять оператор orderby:


int[] numbers = { 3, 12, 4, 10};
var orderedNumbers = from i in numbers
                     orderby i
                     select i;
foreach (int i in orderedNumbers)
    Console.WriteLine(i);

Оператор orderby принимает критерий сортировки. В данном случае в качестве критерия выступает само число. Результат работы программы:

3
4
10
12

Если числа сортируются стандартным образом, как принято в математике, то строки сортируются исходя из алфавитного порядка:


string[] people = { "Tom", "Bob", "Sam" };
var orderedPeople = from p in people orderby p select p;
foreach (var p in orderedPeople)
    Console.WriteLine(p);       // Bob Sam Tom

Вместо оператора orderby можно применять метод расширения OrderBy():


OrderBy (Func<TSource,TKey> keySelector)
OrderBy (Func<TSource,TKey> keySelector, IComparer<TKey>? comparer);

Первая версия метода получает делегат, который через параметр получает элемент коллекции и который возвращает значение, применяемое для сортировки. Вторая версия позволяет также задать принцип сортировки через реализацию интерфейса IComparer.

Перепишем предыдущие два примера с помощью метода OrderBy:


int[] numbers = { 3, 12, 4, 10 };
var orderedNumbers = numbers.OrderBy(n=>n);
foreach (int i in orderedNumbers)
    Console.WriteLine(i);

string[] people = { "Tom", "Bob", "Sam" };
var orderedPeople = people.OrderBy(p=>p);
foreach (var p in orderedPeople)
    Console.WriteLine(p);

Сортировка сложных объектов

Возьмем посложнее пример. Допустим, надо отсортировать выборку сложных объектов. Тогда в качестве критерия мы можем указать свойство класса объекта:


var people = new List<Person>
{
    new Person("Tom", 37),
    new Person("Sam", 28),
    new Person("Tom", 22),
    new Person("Bob", 41),
};
// с помощью оператора orderby
var sortedPeople1 = from p in people
                  orderby p.Name
                  select p;

foreach (var p in sortedPeople1)
    Console.WriteLine($"{p.Name} - {p.Age}");

// с помощью метода OrderBy
var sortedPeople2 = people.OrderBy(p => p.Name);

foreach (var p in sortedPeople2)
    Console.WriteLine($"{p.Name} - {p.Age}");

record class Person(string Name, int Age);

Сортировка по возрастанию и убыванию

По умолчанию оператор orderby и метод OrderBy производят сортировку по возрастанию. С помощью ключевых слов ascending (сортировка по возрастанию) и descending (сортировка по убыванию) для оператора orderby можно явным образом указать направление сортировки. Например, отсортируем массив чисел по убыванию:


int[] numbers = { 3, 12, 4, 10 };
var orderedNumbers = from i in numbers
                     orderby i descending
                     select i;
foreach (int i in orderedNumbers)
    Console.WriteLine(i);   // 12 10 4 3

Для сортировки по убыванию можно применять метод OrderByDescending(), который работает аналогично OrderBy за исключением направления сортировки:


int[] numbers = { 3, 12, 4, 10 };
var orderedNumbers = numbers.OrderByDescending(n => n);
foreach (int i in orderedNumbers)
    Console.WriteLine(i);   // 12 10 4 3

Множественные критерии сортировки

В наборах сложных объектов иногда встает ситуация, когда надо отсортировать не по одному, а сразу по нескольким полям. Для этого в запросе LINQ все критерии указываются в порядке приоритета через запятую:


var people = new List<Person>
{
    new Person("Tom", 37),
    new Person("Sam", 28),
    new Person("Tom", 22),
    new Person("Bob", 41),
};
// с помощью оператора orderby
var sortedPeople1 = from p in people
                  orderby p.Name, p.Age
                  select p;

foreach (var p in sortedPeople1)
    Console.WriteLine($"{p.Name} - {p.Age}");

Результат программы:

Bob - 41
Sam - 28
Tom - 22
Tom - 37

Для разных критериев сортировки можно установить направление:


// с помощью оператора orderby
var sortedPeople1 = from p in people
                  orderby p.Name, p.Age descending  // сортировка по возрасту по убыванию
                  select p;

С помощью методов расширения то же самое можно сделать через метод ThenBy()(для сортировки по возрастанию) и ThenByDescending() (для сортировки по убыванию):


var sortedPeople2 = people.OrderBy(p => p.Name).ThenByDescending(p=>p.Age);

Результат будет аналогичен предыдущему.

Переопределение критерия сортировки

С помощью реализации IComparer мы можем переопределить критерии сортировки, если они нас не устраивают. Например, строки по умолчанию сортируются в алфавитном порядке. Но что, если мы хотим сортировать строки исходя из их длины? Решим данную задачу:


string[] people = new[]{"Kate", "Tom", "Sam", "Mike", "Alice"};
var sortedPeople = people.OrderBy(p => p, new CustomStringComparer());

foreach (var p in sortedPeople)
    Console.WriteLine(p);

// сравнение по длине строки
class CustomStringComparer : IComparer<String>
{
    public int Compare(string? x, string? y)
    {
        int xLength = x?.Length ?? 0; // если x равно null, то длина 0
        int yLength = y?.Length ?? 0;
        return xLength - yLength;
    }
}

Интерфейс IComparer типизируется типов сортируемых данных (в данном случае типом String). Для реализации этого интерфейса необходимо определить метод Compare. Он возвращает число: если первый параметр больше второго, то число больше 0, если меньше - то число меньше 0. Если оба параметра равны, то возвращается 0.

В данном случае, если параметр равен null, будем считать что длина строки равна 0. И с помощью разницы длин строк из обоих параметров определяем, какой из них больше.

Результат программы:

Tom
Sam
Kate
Mike
Alice

Проверь себя

📋 Тест по теме «Сортировка» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

int[] _____ = { 3, 12, 4, 10};
var orderedNumbers = from i in numbers
                     orderby i
                     select i;
foreach (int i in orderedNumbers)
    Console.WriteLine(i);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

string[] people = { "_____", "Bob", "Sam" };
var orderedPeople = from p in people orderby p select p;
foreach (var p in orderedPeople)
    Console.WriteLine(p);       // Bob Sam Tom
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

OrderBy (Func<_____,TKey> keySelector)
OrderBy (Func<TSource,TKey> keySelector, IComparer<TKey>? comparer);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

int[] numbers = { 3, 12, _____, 10 };
var orderedNumbers = numbers.OrderBy(n=>n);
foreach (int i in orderedNumbers)
    Console.WriteLine(i);

string[] people = { "Tom", "Bob", "Sam" };
var orderedPeople = people.OrderBy(p=>p);
foreach (var p in orderedPeople)
    Console.WriteLine(p);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

var people = _____ List<Person>
{
    new Person("Tom", 37),
    new Person("Sam", 28),
    new Person("Tom", 22),
    new Person("Bob", 41),
};
// с помощью оператора orderby
var sortedPeople1 = from p in people
                  orderby p.Name
                  select p;

foreach (var p in sortedPeople1)
    Console.WriteLine($"{p.Name} - {p.Age}");

// с помощью метода OrderBy
var sortedPeople2 = people.OrderBy(p => p.Name);

foreach (var p in sortedPeople2)
    Console.WriteLine($"{p.Name} - {p.Age}");

record class Person(string Name, int Age);
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

int[] numbers = { 3, 12, 4, _____};
var _____ = from i in numbers
                     orderby i
                     select i;
foreach (int i in orderedNumbers)
    Console.WriteLine(i);
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

string[] _____ = { "Tom", "Bob", "Sam" };
var orderedPeople = from p in people orderby p _____ p;
foreach (var p in orderedPeople)
    Console.WriteLine(p);       // Bob Sam Tom
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

                     select i;
int[] numbers = { 3, 12, 4, 10};
var orderedNumbers = from i in numbers
    Console.WriteLine(i);
                     orderby i
foreach (int i in orderedNumbers)
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Сортировка»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Сортировка», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

int[] numbers = { 3, 12, 4, 10};
var orderedNumbers = from i in numbers
                     orderby i
                     select i;
foreach (int i in orderedNumbers)
    Console.WriteLine(i);
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Сортировка»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

string[] people = { "Tom", "Bob", "Sam" };
var orderedPeople = from p in people orderby p select p;
foreach (var p in orderedPeople)
    Console.WriteLine(p);       // Bob Sam Tom
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Сортировка»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Сортировка»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Сортировка». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.