Перейти к основному содержимому

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

Фильтрация — это отбор тех элементов коллекции, которые соответствуют условию.

Условие записывается как функция, которая принимает один элемент и возвращает true (оставить его) или false (пропустить его). Такая функция называется предикатом.

Фильтрация строит новый массив. Исходный массив не изменяется.

У массивов уже есть метод filter(), поэтому свою вспомогательную функцию писать не нужно. Вы вызываете его на массиве и передаёте предикат: words.filter(s => s.length > 3).

Метод filter() есть только у массивов. У Map его нет, поэтому сначала превратите его в массив пар, отфильтруйте этот массив и постройте из результата новый Map.

Будьте осторожны с splice(). Он тоже удаляет элементы, но изменяет исходный массив вместо того, чтобы создать новый.


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

Самый простой способ фильтрации — передать предикат в filter(). Метод проходит по массиву и оставляет каждый элемент, который проходит проверку.

У Map нет своего filter(). Разложите его через [...m] в массив пар [key, value], отфильтруйте эти пары и передайте результат в new Map().

Если условию нужна ещё и позиция элемента, используйте второй аргумент предиката. Это индекс.

Чтобы оставить элементы, которые не соответствуют условию, поставьте перед условием !. Отдельного filterNot() нет.

Массив типа (string | number | null)[] может хранить значения разных типов. Защитник типа — функция, у которой возвращаемый тип записан как v is string, — сообщает TypeScript, какие значения пережили фильтрацию, поэтому результат имеет тип string[]. Тот же приём убирает null и undefined — два значения, которые означают «нет значения».

Фильтрация массива

Оставьте только те слова, которые длиннее 3 букв. Условие s.length > 3 передаётся в filter() как стрелочная функция. Результат — новый массив [ 'three', 'four' ].

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four в массиве строк и использует filter() с предикатом, чтобы оставить слова длиннее 3 букв. Выведите получившийся массив.
Вывод: программа на TypeScript и захваченный вывод
Filter an array

Фильтрация Map

Разложите Map на пары [key, value] и оставьте те пары, ключ которых заканчивается на "1", а значение больше 10. endsWith() проверяет окончание строки. Остаётся только одна пара, поэтому новый Map печатается как Map(1) { 'key11' => 11 }.

Prompt
Напишите программу на TypeScript, которая строит Map из ключей key1, key2, key3, key11 со значениями 1, 2, 3, 11. Разложите Map на пары, оставьте только те пары, ключ которых заканчивается на "1", а значение больше 10, постройте из них новый Map и выведите его.
Вывод: программа на TypeScript и захваченный вывод
Filter a Map

Фильтрация с использованием индекса

Предикат может принимать второй аргумент — индекс элемента. Оставьте слово, только если его индекс не равен 0 и в нём меньше 5 букв.

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four и использует filter() с предикатом, принимающим также индекс. Оставьте слово, только если его индекс не равен 0 и оно короче 5 букв, затем выведите результат.
Вывод: программа на TypeScript и захваченный вывод
Filter using the index

Фильтрация с отрицанием условия

Отбросьте слова из 3 букв или меньше. Условие s.length <= 3 отрицается с помощью !, поэтому остаются только более длинные слова.

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four и использует filter() с условием s.length <= 3, отрицаемым с помощью !, так что слова из 3 букв или меньше отбрасываются. Выведите результат.
Вывод: программа на TypeScript и захваченный вывод
Filter with a negated condition

Фильтрация по типу

Массив содержит null, два числа и две строки. Защитник типа (v): v is string => typeof v === "string" оставляет только строки, а также сужает тип: strings имеет тип string[], поэтому для его элементов разрешён toUpperCase(). Каждая строка выводится в верхнем регистре, по одной на строку.

Prompt
Напишите программу на TypeScript с массивом типа (string | number | null)[], содержащим null, 1, "two", 3.5 и "four". Отфильтруйте его защитником типа, у которого возвращаемый тип — v is string, чтобы результат имел тип string[]. Выведите каждую строку в верхнем регистре, по одной на строку.
Вывод: программа на TypeScript и захваченный вывод
Filter by type

Удаление null и undefined

Массив содержит строки вперемешку с null и undefined. Защитник типа оставляет значения, которые не являются ни тем, ни другим, поэтому результат имеет тип string[] — нулевая часть типа исчезла, и строки можно использовать без дополнительной проверки.

Prompt
Напишите программу на TypeScript с массивом типа (string | null | undefined)[], содержащим null, "one", undefined и "two". Отфильтруйте его защитником типа, который убирает null и undefined, чтобы результат имел тип string[]. Выведите результат.
Вывод: программа на TypeScript и захваченный вывод
Filter out null and undefined

Разбиение

Иногда нужны обе группы: элементы, которые соответствуют условию, и те, которые не соответствуют.

Встроенного partition() нет. С этим справляется небольшая обобщённая вспомогательная функция: она проходит по массиву один раз и помещает каждый элемент либо в массив match, либо в массив rest. Функция возвращает оба массива как кортеж — массив с фиксированной длиной и типом для каждой позиции, — а вы распаковываете его с помощью const [match, rest] = ....

Разделение массива надвое

Слова длиннее 3 букв попадают в match; все остальные попадают в rest. Оба массива выводятся на двух строках.

Prompt
Напишите программу на TypeScript с обобщённой вспомогательной функцией partition, которая разбивает массив на кортеж из двух массивов: элементы, прошедшие условие, и все остальные. Примените её к словам one, two, three, four с условием «длиннее 3 букв», затем выведите массив подходящих элементов и остальные на двух строках.
Вывод: программа на TypeScript и захваченный вывод
Split an array in two

Проверка предикатов

Иногда вам нужны не сами подходящие элементы, а только ответ «да» или «нет».

  • any: проходит ли проверку хотя бы один элемент? На это отвечает some().
  • none: не проходит ли проверку ни один элемент? Поставьте ! перед some().
  • all: проходит ли проверку каждый элемент? Это every().

Оба метода останавливаются, как только ответ известен. some() останавливается на первом элементе, который прошёл проверку, а every() — на первом, который её не прошёл.

Без условия вопрос «есть ли хоть один элемент?» — это words.length > 0, а «нет ни одного элемента?» — это words.length === 0.

На пустом массиве every() возвращает true. Нет ни одного элемента, который не прошёл бы проверку, поэтому проверка ни разу не нарушена. Это называется тривиальной истиной.

any

Проверьте, заканчивается ли хотя бы одно слово на "e", а затем проверьте, есть ли в массиве хоть один элемент. Оба ответа — true.

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four. С помощью some() проверьте, заканчивается ли хотя бы одно слово на "e", и выведите ответ. Затем выведите, есть ли в массиве хоть один элемент, проверив, что его длина больше 0.
Вывод: программа на TypeScript и захваченный вывод
any

none

Проверьте, что ни одно слово не заканчивается на "a" — это true, — а затем проверьте, пуст ли массив, что даёт false.

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four. С помощью ! и some() проверьте, что ни одно слово не заканчивается на "a", и выведите ответ. Затем выведите, пуст ли массив, проверив, что его длина равна 0.
Вывод: программа на TypeScript и захваченный вывод
none

all

Проверьте, каждое ли слово заканчивается на "e". Слово "two" не заканчивается, поэтому ответ — false. Затем вызовите every() на пустом массиве, что даёт true.

Prompt
Напишите программу на TypeScript, которая берёт слова one, two, three, four. С помощью every() проверьте, все ли они заканчиваются на "e", и выведите ответ. Затем вызовите every() с тем же условием на пустом массиве строк и выведите ответ.
Вывод: программа на TypeScript и захваченный вывод
all