Array.prototype.find()
The find() method returns the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
- If you need the index of the found element in the array, use findIndex() .
- If you need to find the index of a value, use indexOf() . (It’s similar to findIndex() , but checks each element for equality with the value instead of using a testing function.)
- If you need to find if a value exists in an array, use includes() . Again, it checks each element for equality with the value instead of using a testing function.
- If you need to find if any element satisfies the provided testing function, use some() .
Try it
Syntax
Parameters
A function to execute for each element in the array. It should return a truthy value to indicate a matching element has been found, and a falsy value otherwise. The function is called with the following arguments:
The current element being processed in the array.
The index of the current element being processed in the array.
The array find() was called upon.
A value to use as this when executing callbackFn . See iterative methods.
Return value
The first element in the array that satisfies the provided testing function. Otherwise, undefined is returned.
Description
The find() method is an iterative method. It calls a provided callbackFn function once for each element in an array in ascending-index order, until callbackFn returns a truthy value. find() then returns that element and stops iterating through the array. If callbackFn never returns a truthy value, find() returns undefined .
callbackFn is invoked for every index of the array, not just those with assigned values. Empty slots in sparse arrays behave the same as undefined .
find() does not mutate the array on which it is called, but the function provided as callbackFn can. Note, however, that the length of the array is saved before the first invocation of callbackFn . Therefore:
- callbackFn will not visit any elements added beyond the array’s initial length when the call to find() began.
- Changes to already-visited indexes do not cause callbackFn to be invoked on them again.
- If an existing, yet-unvisited element of the array is changed by callbackFn , its value passed to the callbackFn will be the value at the time that element gets visited. Deleted elements are visited as if they were undefined .
Warning: Concurrent modifications of the kind described above frequently lead to hard-to-understand code and are generally to be avoided (except in special cases).
The find() method is generic. It only expects the this value to have a length property and integer-keyed properties.
The array find method and alternatives in vanilla javaScript
A long time ago I wrote a post on the lodash find method that is a way to go about finding a single element in an array. Lodash might still not be a dead library just yet, but I have to say that for the most part I am just making use of native javaScript features to do much of what can be done with lodash. One such method that might come to mind is the native array find method of the array prototype I native javaScript. There is also the array find index method that works just the same as the array find method only it will return an index rather than a value.
In many respects the array find method is just like the lodash fine method. There may be some talking points as to why the native array find method might not be a drop in replacement for the loadash fine method with respect to all use case scenarios. However there are many other native javaScript features that can be used to even over come those other situations in which the lodash fine method will work where the native array find method will not.
There is also not just the question of using the native array find method or the lodash fine method, there are many other lodash method of course, and there are also many tools to work with in core javaScript also. Most of the time I can not say that I use the find methods if any kind to find something actually oddly enough. There is also many other lodash methods such as the lodash filter method, as well as the native array filter method that can also be used to find not just the first element, but all elements that meet a condition. There is also the question of how to go about sorting the results of what I get from filtering an array. So in this post I will be touching base on the array find method, but I will also be looking into what other methods there are to work with when it comes to finding something.
1 — Basic examples of the array find method
To start out with there is just playing around with a few basic examples of the array find method. So in this section I will just be doing just that with some basic examples that just involve finding the first value in an array from left to right with the array find method. The focus here will just be on the array find method for the most part, and keeping the examples fairly simple. Alter in this post I will be getting into some alternatives array methods and features in javaScript that might prove to also be useful ways to go about finding something in an array.
1.1 — Simple array find numbers example
In this example I am using the array find method to just fine the first number in an array that is greater than 2.
1.2 — The arguments used in the call back function
When writing the call back function that will be passed to the array find method there are a number of arguments that will be available in the body of the call back function. The first argument is the current value of an element in the array, the second is that values index in the array, and the final argument is a reference to the array itself.
2 — Some alternative methods, and javaScript features, that can be used to help find something
So now that I covered the basics of the array find prototype method it now might be a good idea to look into some alternative ways to go about finding something in an array in native javaScript. The array find method will work okay for what it is intended for, but it does have its limitations. For example some times I might not just want to find the element that will meet a condition from left to right in an array, some times I might want to do the same but from the right to the left. Also often I might not just want to find one element, but all elements that meet a given condition. Also there may be times where I will not just want to get an element, or a collection of elements, but sort an array by way of a condition. That way the first element in the array would be the best fit, followed by the second runner up, and so forth.
2.1 — The array filter method
If I want to get not just one element, but all elements that meet a condition I can use the array filter method. This will create and return a new array where each element is an element that meets the conditon that was given with a callback rather than just the first match.
2.2 — Using array reverse to change the direction from which to find something
Say I want to use the array find method as it will work just fine, but I just want to reverse the order in which the array find method works. For this the array reverse method can reverse the order of all the elements, and then it will get the first element that will meet the condition from what was the end of the array before hand.
2.3 — Find the biggest and smallest numbers with Math min and max methods combined Function.apply
The Math.max and Math.min methods of the Math object can be used as a way to go about finding the largest, or smallest number in an array when using with the apply function prototype method. To do this I just need to pas something like null as the value for the value of this when calling the apply method off of the Math.max, or Math.min method, and then the array as the second argument for the apply method.
When it comes to finding the smallest value for an array of objects I will want to do something to create an array of numbers that I can then pass to one of these math methods. Doing something with the array map method can be done to furnish such an array from an array of objects.
2.4 — The array sort method to change the order of the whole array where the first element is the best match
I covered the array filter method as a way to go about creating a new array that is a collection of elements that meet the condition given rather than just the first match like the array find method does. However there is also sorting an array in place so that the first element of the array is the best match when it comes to finding something, and then the nest is the next best match, and so on. In vanilla javaScript there is learning how to do about using the array sort method when it comes to doing this sort of thing.
This way I am sorting the whole array so that it is in order with respect to the condition in which I want to find something, rather than just getting the first match from left to right which would be the case when just using the array find method by itself.
3 — Conclusion
The array fine method is then one way to go about finding one element in an array that will match a given condition in the from of an expression in a call back function. However there are many other methods and features that can also be used to get the first element, as well as all the elements that meet a condition. There are also ways of going about creating a whole new array from a source array, creating values that will be used as a kind of score, and then sorting the new array by that score or index value.
Методы массива JS
Массивы предоставляют множество методов. Чтобы было проще, в этой главе они разбиты на группы.
Добавление/удаление элементов#
Метод splice( )#
Как удалить элемент из массива?
Так как массивы – это объекты, то можно попробовать delete:
Вроде бы, элемент и был удалён, но при проверке оказывается, что массив всё ещё имеет 3 элемента arr.length == 3 .
Это нормально, потому что всё, что делает delete obj.key – это удаляет значение с данным ключом key . Это нормально для объектов, но для массивов мы обычно хотим, чтобы оставшиеся элементы сдвинулись и заняли освободившееся место. Мы ждём, что массив станет короче.
Поэтому для этого нужно использовать специальные методы.
Метод arr.splice(str) – это универсальный «швейцарский нож» для работы с массивами. Умеет всё: добавлять, удалять и заменять элементы.
Он начинает с позиции index , удаляет deleteCount элементов и вставляет elem1, . elemN на их место. Возвращает массив из удалённых элементов.
Этот метод проще всего понять, рассмотрев примеры.
Начнём с удаления:
Легко, правда? Начиная с позиции 1, он убрал 1 элемент.
В следующем примере мы удалим 3 элемента и заменим их двумя другими.
Здесь видно, что splice возвращает массив из удалённых элементов:
Метод splice также может вставлять элементы без удаления, для этого достаточно установить deleteCount в 0 :
Отрицательные индексы разрешены
В этом и в других методах массива допускается использование отрицательного индекса. Он позволяет начать отсчёт элементов с конца, как тут:
Метод slice( )#
Метод arr.slice намного проще, чем похожий на него arr.splice.
Он возвращает новый массив, в который копирует элементы, начиная с индекса start и до end (не включая end). Оба индекса start и end могут быть отрицательными. В таком случае отсчёт будет осуществляться с конца массива.
Это похоже на строковый метод str.slice , но вместо подстрок возвращает подмассивы.
Можно вызвать slice и вообще без аргументов: arr.slice() создаёт копию массива arr. Это часто используют, чтобы создать копию массива для дальнейших преобразований, которые не должны менять исходный массив.
Метод concat( )#
Метод arr.concat создаёт новый массив, в который копирует данные из других массивов и дополнительные значения.
Он принимает любое количество аргументов, которые могут быть как массивами, так и простыми значениями.
В результате мы получаем новый массив, включающий в себя элементы из arr , а также arg1, arg2 и так далее…
Если аргумент argN – массив, то все его элементы копируются. Иначе скопируется сам аргумент.
Обычно он просто копирует элементы из массивов. Другие объекты, даже если они выглядят как массивы, добавляются как есть:
…Но если объект имеет специальное свойство Symbol.isConcatSpreadable , то он обрабатывается concat как массив: вместо него добавляются его числовые свойства.
Для корректной обработки в объекте должны быть числовые свойства и length :
Метод forEach( )#
Метод arr.forEach позволяет запускать функцию для каждого элемента массива.
Например, этот код выведет на экран каждый элемент массива:
А этот вдобавок расскажет и о своей позиции в массиве:
Результат функции (если она вообще что-то возвращает) отбрасывается и игнорируется.
Поиск в массиве#
Методы indexOf/lastIndexOf и includes#
Далее рассмотрим методы, которые помогут найти что-нибудь в массиве. Методы arr.indexOf, arr.lastIndexOf и arr.includes имеют одинаковый синтаксис и делают по сути то же самое, что и их строковые аналоги, но работают с элементами вместо символов:
arr.indexOf(item, from)#
arr.lastIndexOf(item, from)#
arr.includes(item, from)#
Обратите внимание, что методы используют строгое сравнение === . Таким образом, если мы ищем false , он находит именно false , а не ноль .
Если мы хотим проверить наличие элемента, и нет необходимости знать его точный индекс, тогда предпочтительным является arr.includes .
Кроме того, очень незначительным отличием includes является то, что он правильно обрабатывает NaN в отличие от indexOf/lastIndexOf :
Методы find и findIndex#
Представьте, что у нас есть массив объектов. Как нам найти объект с определённым условием?
Здесь пригодится метод arr.find .
Его синтаксис таков:
Функция вызывается по очереди для каждого элемента массива:
- item – очередной элемент.
- index – его индекс.
- array – сам массив.
Если функция возвращает true , поиск прерывается и возвращается item . Если ничего не найдено, возвращается undefined .
Например, у нас есть массив пользователей, каждый из которых имеет поля id и name . Попробуем найти того, кто с id == 1 :
В реальной жизни массивы объектов – обычное дело, поэтому метод find крайне полезен.
Обратите внимание, что в данном примере мы передаём find функцию item => item.id == 1 , с одним аргументом. Это типично, дополнительные аргументы этой функции используются редко.
Метод arr.findIndex – по сути, то же самое, но возвращает индекс, на котором был найден элемент, а не сам элемент, и -1, если ничего не найдено.
Метод filter( )#
Метод find ищет один (первый попавшийся) элемент, на котором функция-колбэк вернёт true .
На тот случай, если найденных элементов может быть много, предусмотрен метод arr.filter(fn) .
Синтаксис этого метода схож с find , но filter возвращает массив из всех подходящих элементов:
Преобразование массива#
Перейдём к методам преобразования и упорядочения массива.
Метод map( )#
Метод arr.map является одним из наиболее полезных и часто используемых.
Он вызывает функцию для каждого элемента массива и возвращает массив результатов выполнения этой функции.
Например, здесь мы преобразуем каждый элемент в его длину:
Метод sort( )#
Вызов arr.sort() сортирует массив на месте, меняя в нём порядок элементов.
Он возвращает отсортированный массив, но обычно возвращаемое значение игнорируется, так как изменяется сам arr.
Не заметили ничего странного в этом примере?
Порядок стал 1, 15, 2 . Это неправильно! Но почему?
По умолчанию элементы сортируются как строки.
Буквально, элементы преобразуются в строки при сравнении. Для строк применяется лексикографический порядок, и действительно выходит, что "2" > "15" .
Чтобы использовать наш собственный порядок сортировки, нам нужно предоставить функцию в качестве аргумента arr.sort() .
Функция должна для пары значений возвращать:
Например, для сортировки чисел:
Теперь всё работает как надо.
Давайте возьмём паузу и подумаем, что же происходит. Упомянутый ранее массив arr может быть массивом чего угодно, верно? Он может содержать числа, строки, объекты или что-то ещё. У нас есть набор каких-то элементов. Чтобы отсортировать его, нам нужна функция, определяющая порядок, которая знает, как сравнивать его элементы. По умолчанию элементы сортируются как строки.
Метод arr.sort(fn) реализует общий алгоритм сортировки. Нам не нужно заботиться о том, как он работает внутри (в большинстве случаев это оптимизированная быстрая сортировка). Она проходится по массиву, сравнивает его элементы с помощью предоставленной функции и переупорядочивает их. Всё, что остаётся нам, это предоставить fn , которая делает это сравнение.
Кстати, если мы когда-нибудь захотим узнать, какие элементы сравниваются – ничто не мешает нам вывести их на экран:
В процессе работы алгоритм может сравнивать элемент с другими по нескольку раз, но он старается сделать как можно меньше сравнений.
Функция сравнения может вернуть любое число
На самом деле от функции сравнения требуется любое положительное число, чтобы сказать «больше», и отрицательное число, чтобы сказать «меньше».
Поиск элементов в массиве JavaScript
Для поиска по массиву в JavaScript существует несколько методов прототипа Array, не считая что поиск можно выполнить и методами для перебора массива и в обычном цикле.
Итак, мы сегодня рассмотрим следующие варианты:
- Array.includes()
- Array.indexOf()
- Array.find()
- Array.findIndex()
- Array.filter()
- Array.forEach()
Array.includes() — есть ли элемент в массиве
Данный метод ищет заданный элемент и возвращает true или false , в зависимости от результата поиска. Принимает два параметра:
- element — то, что мы будем искать
- fromIndex (необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
Как видно из примера выше, в первом случае мы получим true , т.к. начали с нулевого элемента массива. Во втором случае мы передали второй параметр — индекс, с которого нужно начать поиск — и получили false , т.к. дальше элемент не был найден.
Array.indexOf() — индекс элемента в массиве
Данный метод, в отличие от предыдущего, возвращает индекс первого найденного совпадения. В случае если элемент не найден, будет возвращено число -1
Также принимает два параметра:
- element — элемент, который мы будем искать
- fromIndex (необязательный) — с какого индекса начинать поиск. По умолчанию с 0.
Как видно из примера выше, в первом случае мы получаем 0, т.к. сразу нашли первый элемент массива (первое совпадение, дальше поиск уже не выполняется). Во втором случае 4, т.к. начали поиск с индекса 1 и нашли следующее совпадение. В третьем примере мы получили результат -1, т.к. поиск начали с индекса 2, а элемент Orange в нашем массиве под индексом 1.
Так как данный метод возвращает индекс или -1, мы можем присвоить результат в переменную для дальнейшего использования:
Чтобы произвести какие-то действия над найденным элементом массива, мы можем использовать следующий синтаксис:
Примеры использования данного метода вы можете также найти в посте про удаление элемента из массива
Array.find() — найти элемент по условию
Данный метод callback и thisArg в качестве аргументов и возвращает первое найденное значение.
Callback принимает несколько аргументов:
item — текущий элемент массива
index — индекс текущего элемента
currentArray — итерируемый массив
Данный метод полезен тем, что мы можем найти и получить сразу и искомый элемент, и его index
Также работа кода прекратиться как только будет найден нужный элемент и второй элемент (дубликат) не будет найден.
В случае если ничего не найдено будет возвращен undefined .
Array.findIndex() — найти индекс элемента в массиве
Этот метод похож на метод find() , но возвращать будет только индекс элемента, который соответствует требованию. В случае, если ничего не найдено, вернет -1
Ну и по аналогии с предыдущим методом, поиск завершается после первого совпадения.
Поиск всех совпадений в массиве
Метод filter() кроме всего остального также можно использовать для поиска по массиву. Предыдущие методы останавливаются при первом соответствии поиска, а данный метод пройдется по массиву до конца и найдет все элементы. Но данный метод вернет новый массив, в который войдут все элементы соответствующие условию.
Как видите из примера выше, первоначальный массив не будет изменен.
Подробнее про метод JS filter() можете прочитать в этом посте.
Для этих же целей можно использовать метод forEach(), который предназначен для перебора по массиву:
В массив indexes мы получили индексы найденных элементов, это 0 и 4 элементы. Также в зависимости от вашей необходимости, можно создать объект, где ключом будет индекс, а значением сам элемент:
Поиск в массиве объектов
Если у вас массив состоит не из примитивных типов данных, а к примеру, каждый элемент это объект со своими свойствами и значениями, тогда можно использовать следующие варианты для получения индекса элемента.
Первый способ. С использованием метода map для массива
В данном случае по массиву arr мы проходим и на каждой итерации из текущего элемента (а это объект со свойствами name и age ) возвращаем имя человека в новый массив и сразу же выполняем поиск по новому массиву на имя Anna. При совпадении нам будет возвращен индекс искомого элемента в массиве.
Второй способ. Данный вариант будет немного проще, т.к. мы можем сразу получить индекс при совпадении:
Заключение
Как видите любой из вышеприведенных методов можно использовать для поиска по массиву. Какой из них использовать зависит от вашей задачи и того, что вам нужно получить — сам элемент или его индекс в массиве, найти только первое совпадение или все совпадения при поиске.