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

Получение одиночных элементов

Этот урок показывает, как получить один элемент из массива: по его позиции, по условию или случайным образом. Он также показывает, как проверить, существует ли элемент вообще.

В TypeScript есть два значения, означающие «нет значения»: null и undefined. Когда поиск может не удаться, ответом будет undefined. Рядом со значением нет второго флага: отсутствующий элемент и есть undefined.

Чтение позиции, которой не существует, например words[5] в массиве из 5 элементов, не останавливает программу. Вы получаете undefined. Тип string | undefined нужен именно для того, чтобы напоминать вам об этом случае.

Чтобы превратить этот undefined в собственное значение, используйте оператор ??. Он берёт правую часть, только когда левая равна null или undefined.

Массивы несут большинство этих инструментов в виде методов: at(), find(), findLast(), includes() и every(). Для остального вы один раз пишете небольшую вспомогательную функцию.


Получение по позиции

У каждого элемента массива есть позиция, которая называется индексом. Первый индекс — 0, поэтому последний равен words.length - 1.

Чтобы прочитать элемент по позиции, напишите индекс в квадратных скобках: words[3]. Для последнего элемента есть также words.at(-1), который отсчитывает от конца.

Несуществующий индекс даёт undefined, а не ошибку. Поэтому честный тип для words[i] — это string | undefined: может быть, там строка, а может быть, ничего.

Методов elementAtOrNull() и elementAtOrElse() нет. Они и не нужны: отсутствующий элемент уже равен undefined, а ?? подставляет вместо него ваше собственное значение.

Элемент по позиции

words[3] читает элемент по индексу 3. Поскольку отсчёт начинается с 0, это четвёртое слово, поэтому программа выводит four.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. Выведите элемент по индексу 3, используя квадратные скобки.
Вывод: программа на TypeScript и захваченный вывод
Element at a position

Первый и последний элемент

Первый элемент — это words[0]. Последний — words.at(-1): at() принимает отрицательный индекс и отсчитывает от конца, поэтому -1 — это последний элемент. Программа выводит one, а затем five.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. Выведите первый элемент по индексу 0, затем последний элемент с помощью at(-1).
Вывод: программа на TypeScript и захваченный вывод
First and last element

Элемент по позиции или undefined

elementAt() просто читает items[i] и говорит об этом в своём возвращаемом типе: T | undefined. Индекс 1 находится в пределах массива, поэтому первый вызов выводит two. Индекс 5 выходит за пределы, поэтому второй вызов выводит undefined — без падения и без второго true или false рядом со значением.

Prompt
Напишите программу на TypeScript с обобщённой вспомогательной функцией elementAt, которая возвращает T | undefined для индекса. Вызовите её для слов one, two, three, four и five с индексом 1 и с индексом 5 и выведите оба результата.
Вывод: программа на TypeScript и захваченный вывод
Element at a position, or undefined

Элемент по позиции или запасное значение

words[5] равно undefined, поэтому ?? берёт правую часть и вызывает fallback(5). Функция получает индекс, поэтому может построить сообщение Значение для индекса 5 равно undefined.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. Прочитайте индекс 5 и используйте ?? с запасной функцией, которая получает индекс и строит текст «Значение для индекса 5 равно undefined». Выведите результат.
Вывод: программа на TypeScript и захваченный вывод
Element at a position, or a fallback

Получение по условию

Часто вы не знаете позицию. Зато вы знаете условие: первое слово длиннее 3 букв, последнее слово, начинающееся с "f". Условие — это функция, которая принимает один элемент и возвращает true или false.

Для первого совпадения у массивов есть find(). Он идёт от начала и возвращает первый элемент, прошедший проверку, или undefined, если не проходит ни один.

findLast() делает тот же обход в другую сторону, от последнего индекса к 0. Первый встреченный элемент — это последнее совпадение в массиве.

Оба метода останавливаются, как только находят совпадение, поэтому остаток массива никогда не проверяется. А поскольку «ничего не совпало» — это просто undefined, вы проверяете результат через !== undefined или задаёте значение по умолчанию через ??.

Первое совпадение

find() возвращает первое слово, для которого s.length > 3. "one" и "two" слишком короткие, поэтому программа выводит three.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. С помощью find() получите первое слово длиннее 3 букв и выведите его.
Вывод: программа на TypeScript и захваченный вывод
First match

Последнее совпадение

findLast() начинает с последнего индекса и движется вниз. Первое встреченное слово, начинающееся с "f", — это "five", поэтому он останавливается там и программа выводит five.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. С помощью findLast() получите последнее слово, начинающееся с "f", и выведите его.
Вывод: программа на TypeScript и захваченный вывод
Last match

Первое совпадение или undefined

Ни одно слово не длиннее 6 букв, поэтому find() возвращает undefined, а ?? "не найдено" заставляет программу вывести не найдено. В массиве чисел первое чётное число — 2; проверка !== undefined — это то, как программа узнаёт, что что-то найдено.

Prompt
Напишите программу на TypeScript, которая ищет среди слов one, two, three, four и five слово длиннее 6 букв и выводит «не найдено» с помощью ??, когда find() возвращает undefined. Затем найдите среди чисел 1, 2, 3, 4 первое чётное число и выведите его, только если результат не равен undefined.
Вывод: программа на TypeScript и захваченный вывод
First match, or undefined

Последнее совпадение или undefined

findLast() проходит числа в обратном порядке, поэтому первое встреченное чётное число — это последнее в массиве: 4, по индексу 3. Оно находится сразу же.

Prompt
Напишите программу на TypeScript с числами 1, 2, 3, 4. С помощью findLast() получите последнее чётное число и выведите его, только если результат не равен undefined.
Вывод: программа на TypeScript и захваченный вывод
Last match, or undefined

Получение первого присутствующего значения

Иногда в массиве есть дыры: несколько элементов равны null или undefined, а вам нужно первое настоящее значение.

Обход снова выполняет find(). Условие — v !== null && v !== undefined.

Если записать его прямо в стрелочную функцию, результат всё равно имел бы тип number | string | null | undefined: проверка выполняется во время выполнения, но тип от этого не меняется. Перенесите проверку в именованную функцию, возвращаемый тип которой — v is number | string (такая функция называется стражем типа), и тип результата сам потеряет null и undefined.

Массив в примере одновременно содержит число, строку и null, поэтому его тип — объединение всех этих типов.

Первое значение, не равное null или undefined

Первый элемент равен null, поэтому он пропускается. Следующий — 0, который не равен ни null, ни undefined, поэтому find() возвращает его и останавливается — "true" так и не проверяется. Обратите внимание, что 0 сохраняется: проверка спрашивает про null и undefined, а не про истинность или ложность.

Prompt
Напишите программу на TypeScript с массивом типа (number | string | null | undefined)[], содержащим null, 0 и "true". Используйте find() со стражем типа, который отсеивает null и undefined, чтобы результат имел тип number | string | undefined, и выведите результат.
Вывод: программа на TypeScript и захваченный вывод
First value that is not null or undefined

Случайный элемент

Чтобы выбрать случайный элемент, выберите случайный индекс. Допустимый индекс — это целое число от 0 до numbers.length - 1.

У массивов нет метода random(), поэтому индекс, как обычно, попадает в квадратные скобки.

Math.random() даёт другое число при каждом запуске. Именно это и нужно в настоящей программе, но тогда этот урок каждый раз выводил бы что-то другое. Поэтому пример инициализирует собственный крошечный генератор фиксированным числом 42. Одно и то же зерно всегда даёт один и тот же индекс, что делает результат воспроизводимым. Используйте Math.random(), когда вам действительно нужен разный элемент при каждом запуске.

Выбор случайного элемента

С зерном 42 генератор выбирает индекс 1, поэтому программа выводит 2. Измените зерно — и может получиться другое число.

Prompt
Напишите программу на TypeScript с числами 1, 2, 3, 4. Инициализируйте небольшой линейный конгруэнтный генератор зерном 42, используйте его, чтобы выбрать индекс от 0 до длины массива минус один, и выведите элемент по этому индексу.
Вывод: программа на TypeScript и захваченный вывод
Pick a random element

Проверка наличия элемента

Чтобы проверить, есть ли значение в массиве, используйте includes(). Он возвращает true или false.

Метода containsAll() нет, но every() даёт вам его в одну строку: wanted.every(v => words.includes(v)) равно true, только когда найдено каждое искомое значение. every() останавливается на первом отсутствующем значении.

Метода isEmpty() тоже нет. Сравнивайте длину: words.length === 0 означает «пусто», а words.length > 0 — «не пусто».

Содержит одно значение

"four" есть в массиве, поэтому первая проверка выводит true. "zero" в массиве нет, поэтому вторая выводит false.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five. С помощью includes() проверьте, есть ли в массиве "four" и есть ли в нём "zero". Выведите оба ответа.
Вывод: программа на TypeScript и захваченный вывод
Contains one value

Содержит все значения

И "four", и "one" есть в массиве, поэтому containsAll() возвращает true. "zero" отсутствует, поэтому второй вызов возвращает false.

Prompt
Напишите программу на TypeScript с обобщённой вспомогательной функцией containsAll, которая с помощью every() и includes() возвращает true, только если каждое искомое значение есть в первом массиве. Проверьте слова one, two, three, four и five на наличие four и one, затем на наличие one и zero. Выведите оба ответа.
Вывод: программа на TypeScript и захваченный вывод
Contains all values

Пусто или не пусто

У empty длина 0, поэтому empty.length === 0 равно true. В words 5 элементов, поэтому words.length > 0 тоже равно true.

Prompt
Напишите программу на TypeScript с массивом из слов one, two, three, four и five и с пустым массивом строк. Выведите, равна ли длина пустого массива 0, а затем — больше ли нуля длина массива слов.
Вывод: программа на TypeScript и захваченный вывод
Empty or not empty