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

Фильтрация коллекции

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

Для выбора элементов из некоторого набора по условию используется метод Where:

Where<TSource> (Func<TSource,bool> predicate)

Этот метод принимает делегат Func<TSource,bool>, который в качестве параметра принимает каждый элемент последовательности и возвращает значение bool. Если элемент соответствует некоторому условию, то возвращается true, и тогда этот элемент передаетсяв коллекцию, которая возвращается из метода Where.

Например, выберем все строки, длина которых равна 3:


string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"

foreach (string person in selectedPeople)
    Console.WriteLine(person);

Если выражение в методе Where для определенного элемента будет равно true (в данном случае выражение p.Length == 3), то данный элемент попадает в результирующую выборку.

Аналогичный запрос с помощью операторов LINQ:


string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = from p in people
                     where p.Length == 3
                     select p;

Другой пример - выберем все четные элементы, которые больше 10.

Фильтрация с помощью операторов LINQ:


int[] numbers = { 1, 2, 3, 4, 10, 34, 55, 66, 77, 88 };
// методы расширения
var evens1 = numbers.Where(i => i % 2 == 0 && i > 10);
// операторы запросов
var evens2 = from i in numbers
            where i%2==0 && i>10
            select i;

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

Допустим, у нас есть класс пользователя:


record class Person(string Name, int Age, List<string> Languages);

Свойство Name представляет имя, свойство Age - возраст пользователя, а список Languages - список языков, которыми владеет пользователь.

Создадим набор пользователей и выберем из них тех, которым больше 25 лет:


var people = new List<Person>
{
    new Person ("Tom", 23, new List<string> {"english", "german"}),
    new Person ("Bob", 27, new List<string> {"english", "french" }),
    new Person ("Sam", 29, new List<string>  { "english", "spanish" }),
    new Person ("Alice", 24, new List<string> {"spanish", "german" })
};

var selectedPeople = from p in people
                     where p.Age > 25
                     select p;

foreach (Person person in selectedPeople)
    Console.WriteLine($"{person.Name} - {person.Age}");

Консольный вывод:

Bob - 27
Sam - 29

Аналогичный запрос с помощью метода расширения Where:


var selectedPeople = people.Where(p=> p.Age > 25);

Сложные фильтры

Теперь рассмотрим более сложные фильтры. Например, в классе пользователя есть список языков, которыми владеет пользователь. Что если нам надо отфильтровать пользователей по языку:


var selectedPeople = from person in people
                    from lang in person.Languages
                    where person.Age < 28
                    where lang == "english"
                    select person;

Результат:

Tom - 23
Bob - 27

Для создания аналогичного запроса с помощью методов расширения применяется метод SelectMany:


var selectedPeople = people.SelectMany(u => u.Languages,
							(u, l) => new { Person = u, Lang = l })
                          .Where(u => u.Lang == "english" && u.Person.Age < 28)
                          .Select(u=>u.Person);

Метод SelectMany() в качестве первого параметра принимает последовательность, которую надо проецировать, а в качестве второго параметра - функцию преобразования, которая применяется к каждому элементу. На выходе она возвращает 8 пар "пользователь - язык" (new { Person = u, Lang = l }), к которым потом применяется фильтр с помощью Where.

Фильтрация по типу данных

Дополнительный метод расширения - OfType() позволяет отфильтровать данные коллекции по определенному типу:


var people= new List<Person>
{
    new Student("Tom"),
    new Person("Sam"),
    new Student("Bob"),
    new Employee("Mike")
};

var students = people.OfType<Student>();

foreach (var student in students)
    Console.WriteLine(student.Name);


record class Person(string Name);
record class Student(string Name): Person(Name);
record class Employee(string Name) : Person(Name);

В данном случае список people содержит объекты трех типов - класса Person и производных типов Student и Employee. И в примере производится фильтрация данных типа Student - для этого метод OfType() типизируется типом Student. Консольный вывод:

Tom
Bob

Проверь себя

📋 Тест по теме «Фильтрация коллекции» Тест по теме

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

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

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

_____<TSource> (Func<TSource,bool> predicate)
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

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

string[] people = { "_____", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"

foreach (string person in selectedPeople)
    Console.WriteLine(person);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

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

string[] people = { "Tom", "_____", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = from p in people
                     where p.Length == 3
                     select p;
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

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

int[] numbers = { 1, 2, _____, 4, 10, 34, 55, 66, 77, 88 };
// методы расширения
var evens1 = numbers.Where(i => i % 2 == 0 && i > 10);
// операторы запросов
var evens2 = from i in numbers
            where i%2==0 && i>10
            select i;
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

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

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

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

Where<TSource> (Func<TSource,_____> _____)
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

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

string[] people = { "Tom", "Alice", "Bob", "_____", "Tim", "Tomas", "Bill" };

var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"

foreach (string _____ in selectedPeople)
    Console.WriteLine(person);
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

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

foreach (string person in selectedPeople)
var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"
string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };
    Console.WriteLine(person);
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Фильтрация коллекции»
+30 XP

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

Where<TSource> (Func<TSource,bool> predicate)
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Фильтрация коллекции»
+30 XP

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

string[] people = { "Tom", "Alice", "Bob", "Sam", "Tim", "Tomas", "Bill" };

var selectedPeople = people.Where(p => p.Length == 3); // "Tom", "Bob", "Sam", "Tim"

foreach (string person in selectedPeople)
    Console.WriteLine(person);
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Фильтрация коллекции»
+50 XP

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

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

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

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

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

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