Перейти к содержимому
Теория · Массивы · урок 6 из 13

Поиск элемента

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

Метод splice вырезает элементы по индексу. А индекс нужного элемента часто неизвестен: известно только значение, например цвет "green". Для такого поиска у массива есть два метода — indexOf и includes:

JavaScript
const colors = ["red", "green", "red"];

console.log(colors.indexOf("red")); // 0
console.log(colors.indexOf("blue")); // -1
console.log(colors.includes("green")); // true
console.log(colors.includes("blue")); // false

Давайте разберём по строкам:

  1. colors.indexOf("red") печатает 0: поиск идёт слева направо и останавливается на первом совпадении.
  2. Второй "red" с индексом 2 метод не замечает.
  3. colors.indexOf("blue") печатает -1: такого элемента нет.
  4. colors.includes("green") печатает true, а для "blue" — false.

Два метода поиска

Оба метода обходят массив так же, как вы шли вдоль ячеек: от индекса 0 к концу. Различаются они тем, что возвращают.

indexOf

Метод indexOf отвечает на вопрос «где лежит?». Он возвращает индекс первого совпадения или -1, если элемента нет. Число -1 выбрано потому, что такого индекса в массиве не бывает.

Берите indexOf, когда индекс нужен дальше: чтобы прочитать соседний элемент или вырезать найденный.

includes

Метод includes отвечает на вопрос «есть ли?». Он возвращает true или false, и его удобно ставить прямо в условие if. Например, if (cart.includes("milk")) читается почти как фраза «если в корзине есть молоко».

Берите includes, когда место элемента не важно, а важен только сам факт.

Как они сравнивают

Тут аналогия с камерой хранения перестаёт работать. Свою сумку вы узнаете и в чужом чехле, а методы сравнивают строго. Оба сравнивают без приведения типов, как ===:

JavaScript
console.log([1, 2].indexOf("1")); // -1
console.log([1, 2].includes("1")); // false
console.log([NaN].indexOf(NaN)); // -1
console.log([NaN].includes(NaN)); // true

Строка "1" не равна числу 1, поэтому её нет среди чисел. А с NaN методы расходятся:

  • indexOf сравнивает через ===, а NaN === NaN даёт false, поэтому NaN не находится;
  • includes делает для NaN исключение и находит его.

Чем indexOf отличается от includes, часто спрашивают на собеседовании. Короткий ответ: indexOf возвращает индекс или -1, includes возвращает true или false, и только includes находит NaN.

Найти и вырезать

Теперь соединим поиск со splice. Чтобы удалить "green", сначала узнаём его индекс, а затем вырезаем один элемент:

JavaScript
const i = colors.indexOf("green");
if (i !== -1) {
    colors.splice(i, 1);
}
console.log(colors.join(" ")); // red red

Проверка i !== -1 здесь обязательна. Без неё при отсутствии элемента получился бы вызов splice(-1, 1). А отрицательный индекс и здесь отсчитывается от конца, так что вырезался бы последний элемент.

Частая ошибка

Результат indexOf поставили прямо в условие:

JavaScript
const colors = ["red", "green"];

if (colors.indexOf("red")) { // ✗
    console.log("found");
}

Ошибки нет, но программа ничего не печатает. Элемент "red" стоит первым, и indexOf возвращает 0, а 0 — ложное значение. Зато для отсутствующего элемента -1 — истинное значение, и условие сработало бы.

Чтобы проверить, есть ли элемент, пишите colors.includes("red") или colors.indexOf("red") !== -1.

Главное

  • indexOf возвращает индекс первого совпадения или -1, а includes — true или false.
  • Оба сравнивают как ===, но только includes находит NaN.
  • Перед splice(i, 1) проверяйте i !== -1: иначе вырежется последний элемент.
  • Результат indexOf не ставят в if сам по себе: индекс 0 — ложное значение.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом