Перебор: forEach
Метод arr.forEach позволяет запускать функцию для каждого элемента массива.
Его синтаксис:
arr.forEach(function(item, index, array) {
// ... делать что-то с item
});
Например, этот код выведет на экран каждый элемент массива:
// Вызов alert для каждого элемента
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);
А этот вдобавок расскажет и о своей позиции в массиве:
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
alert(`${item} имеет позицию ${index} в ${array}`);
});
Результат функции (если она вообще что-то возвращает) отбрасывается и игнорируется.
Поиск в массиве
Далее рассмотрим методы, которые помогут найти что-нибудь в массиве.
indexOf/lastIndexOf и includes
Методы arr.indexOf, arr.lastIndexOf и arr.includes имеют одинаковый синтаксис и делают по сути то же самое, что и их строковые аналоги, но работают с элементами вместо символов:
arr.indexOf(item, from)ищетitem, начиная с индексаfrom, и возвращает индекс, на котором был найден искомый элемент, в противном случае-1.arr.lastIndexOf(item, from)– то же самое, но ищет справа налево.arr.includes(item, from)– ищетitem, начиная с индексаfrom, и возвращаетtrue, если поиск успешен.
Например:
let arr = [1, 0, false];
alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1
alert( arr.includes(1) ); // true
Обратите внимание, что методы используют строгое сравнение ===. Таким образом, если мы ищем false, он находит именно false, а не ноль.
Если мы хотим проверить наличие элемента, и нет необходимости знать его точный индекс, тогда предпочтительным является arr.includes.
Кроме того, очень незначительным отличием includes является то, что он правильно обрабатывает NaN в отличие от indexOf/lastIndexOf:
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (должен быть 0, но === проверка на равенство не работает для NaN)
alert( arr.includes(NaN) );// true (верно)
find и findIndex
Представьте, что у нас есть массив объектов. Как нам найти объект с определённым условием?
Здесь пригодится метод arr.find.
Его синтаксис таков:
let result = arr.find(function(item, index, array) {
// если true - возвращается текущий элемент и перебор прерывается
// если все итерации оказались ложными, возвращается undefined
});
Функция вызывается по очереди для каждого элемента массива:
item– очередной элемент.index– его индекс.array– сам массив.
Если функция возвращает true, поиск прерывается и возвращается item. Если ничего не найдено, возвращается undefined.
Например, у нас есть массив пользователей, каждый из которых имеет поля id и name. Попробуем найти того, кто с id == 1:
let users = [
{id: 1, name: "Вася"},
{id: 2, name: "Петя"},
{id: 3, name: "Маша"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // Вася
В реальной жизни массивы объектов – обычное дело, поэтому метод find крайне полезен.
Обратите внимание, что в данном примере мы передаём find функцию item => item.id == 1, с одним аргументом. Это типично, дополнительные аргументы этой функции используются редко.
Метод arr.findIndex – по сути, то же самое, но возвращает индекс, на котором был найден элемент, а не сам элемент, и -1, если ничего не найдено.
filter
Метод find ищет один (первый попавшийся) элемент, на котором функция-колбэк вернёт true.
На тот случай, если найденных элементов может быть много, предусмотрен метод arr.filter(fn).
Синтаксис этого метода схож с find, но filter возвращает массив из всех подходящих элементов:
let results = arr.filter(function(item, index, array) {
// если true - элемент добавляется к результату, и перебор продолжается
// возвращается пустой массив в случае, если ничего не найдено
});
Например:
let users = [
{id: 1, name: "Вася"},
{id: 2, name: "Петя"},
{id: 3, name: "Маша"}
];
// возвращает массив, состоящий из двух первых пользователей
let someUsers = users.filter(item => item.id < 3);
alert(someUsers.length); // 2