Кратко
СкопированоМетод find возвращает индекс первого найденного в массиве элемента, который подходит под условие переданной функции. Если же ни одного подходящего элемента не найдётся, то метод вернёт -1.
Пример
СкопированоНапишем код, который позволит найти человека в списке гостей мероприятия. Для этого определим функцию, которая будет получать имя из массива участников и сверять его с константой guest. Затем передадим эту функцию в метод find:
function isWantedGuest(element, index, array) { const guestName = 'Лиза' return element === guestName}const partyGuests = [ 'Даня', 'Саша', 'Юля', 'Лиза', 'Егор']const meetingGuests = [ 'Даня', 'Егор', 'Арсений']console.log(partyGuests.findIndex(isWantedGuest))// 3 (так как partyGuests[3] -> 'Лиза')console.log(meetingGuests.findIndex(isWantedGuest))// -1 (совпадений нет)
function isWantedGuest(element, index, array) {
const guestName = 'Лиза'
return element === guestName
}
const partyGuests = [
'Даня',
'Саша',
'Юля',
'Лиза',
'Егор'
]
const meetingGuests = [
'Даня',
'Егор',
'Арсений'
]
console.log(partyGuests.findIndex(isWantedGuest))
// 3 (так как partyGuests[3] -> 'Лиза')
console.log(meetingGuests.findIndex(isWantedGuest))
// -1 (совпадений нет)
Интерактивный пример
СкопированоКак пишется
СкопированоМетод find обходит массив и возвращает индекс первого элемента, который подходит под условие функции-предиката. Если ничего не подошло, то он возвращает -1.
Функция, которую мы передаём в метод find, может принимать три параметра:
element— элемент массива в текущей итерации;index— индекс текущего элемента;array— сам массив, который перебираем.
Определим функцию is, которая проверяет, является ли число чётным, то есть делится на два без остатка. А затем найдём в массиве индекс первого такого числа через find.
// Если число чётное — вернёт true,// если нечётное — falsefunction isEven(element) { return element % 2 === 0}const onlyOddNumbers = [1, 3, 5, 7, 9]const randomNumbers = [7, 1, 6, 3, 5]console.log(onlyOddNumbers.findIndex(isEven))// -1 (элемент не найден)console.log(randomNumbers.findIndex(isEven))// 2 (так как randomNumbers[2] -> 6)
// Если число чётное — вернёт true,
// если нечётное — false
function isEven(element) {
return element % 2 === 0
}
const onlyOddNumbers = [1, 3, 5, 7, 9]
const randomNumbers = [7, 1, 6, 3, 5]
console.log(onlyOddNumbers.findIndex(isEven))
// -1 (элемент не найден)
console.log(randomNumbers.findIndex(isEven))
// 2 (так как randomNumbers[2] -> 6)
В этом примере функция is не использует параметры index и array, поэтому мы не стали их объявлять.
Как понять
СкопированоНайти индекс первого подходящего элемента можно и с помощью цикла for, но метод find позволяет сделать это декларативно. С помощью функции-колбэка мы описываем, какой элемент мы ищем и не описываем как должен происходить поиск. Поиск с помощью цикла for содержал бы гораздо больше деталей.
Давайте сами попробуем реализовать find, чтобы лучше понять, как он работает «под капотом».
function findIndex(array, predicate) { for (let i = 0; i < array.length; i++) { // Если элемент удовлетворяет условию, // то возвращаем его индекс if (predicate(array[i], i, array)) { return i } } // Если ничего не подошло, // то возвращаем -1 return -1}function isEven(element) { return element % 2 === 0}const onlyOddNumbers = [1, 3, 5, 7, 9]const randomNumbers = [7, 1, 6, 3, 5]console.log(findIndex(onlyOddNumbers, isEven))// -1console.log(findIndex(randomNumbers, isEven))// 2
function findIndex(array, predicate) {
for (let i = 0; i < array.length; i++) {
// Если элемент удовлетворяет условию,
// то возвращаем его индекс
if (predicate(array[i], i, array)) {
return i
}
}
// Если ничего не подошло,
// то возвращаем -1
return -1
}
function isEven(element) {
return element % 2 === 0
}
const onlyOddNumbers = [1, 3, 5, 7, 9]
const randomNumbers = [7, 1, 6, 3, 5]
console.log(findIndex(onlyOddNumbers, isEven))
// -1
console.log(findIndex(randomNumbers, isEven))
// 2
Подсказки
Скопировано💡 Если используете find в условии, то всегда явно проверяйте возвращаемое значение на -1.
На практике
Скопированосоветует
Скопировано🛠 indexOf или findIndex
СкопированоПомимо find, у массивов есть ещё и метод index. Он работает схожим образом: возвращает индекс первого подходящего элемента или -1, но, в отличие от find, принимает как аргумент не функцию-предикат, а искомое значение.
const numbers = [1, 7, 4, 6, 2, 8, 3]console.log(numbers.indexOf(2))// 4 (значение 2 хранится по индексу 4)numbers.findIndex((element) => element === 2)// 4
const numbers = [1, 7, 4, 6, 2, 8, 3]
console.log(numbers.indexOf(2))
// 4 (значение 2 хранится по индексу 4)
numbers.findIndex((element) => element === 2)
// 4
Кажется, что метод index проще в использовании, и это действительно так, но из-за своей простоты, он уступает методу find в функциональности.
Например, если мы хотим осуществить поиск по массиву объектов, то index вряд ли сможет нам помочь.
const friends = [ { name: 'Андрей' }, { name: 'Маша' }, { name: 'Артём' }]// Элемент не найденconsole.log( friends.indexOf({ name: 'Артём' }))// -1console.log( friends.findIndex( (element) => element.name === 'Артём' ))// 2
const friends = [
{ name: 'Андрей' },
{ name: 'Маша' },
{ name: 'Артём' }
]
// Элемент не найден
console.log(
friends.indexOf({ name: 'Артём' })
)
// -1
console.log(
friends.findIndex(
(element) => element.name === 'Артём'
)
)
// 2
Дело в том, что переменная не хранит в себе содержимое объекта, она содержит только ссылку на него. Следовательно, index сравнивает ссылки, а не сами объекты.
// ссылка на объект 1let tomato = { color: 'red' }// ссылка на объект 2let strawberry = { color: 'red' }
// ссылка на объект 1
let tomato = { color: 'red' }
// ссылка на объект 2
let strawberry = { color: 'red' }
Сравнение этих двух объектов вернёт false несмотря на то, что значения ключей объектов одинаковы. Это происходит, потому что сравниваются ссылки на объекты:
console.log(tomato === strawberry);// falseconsole.log(tomato === tomato)// true
console.log(tomato === strawberry);
// false
console.log(tomato === tomato)
// true