Кратко
СкопированоМетод 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