Поиск в массиве — довольно несложная задача для программиста. На ум сразу приходит перебор через цикл for или бинарный поиск в отсортированном массиве, для элементов которого определены операции «больше» и «меньше». Но, как и любой высокоуровневый язык программирования, JavaScript предлагает разработчику встроенные функции для решения различных задач. В этой статье мы рассмотрим четыре метода поиска в массивах JavaScript: find
, includes
, indexOf
и filter
.
cloud
indexOf
— это функция поиска элемента в массиве. Этот метод с помощью перебора ищет искомый объект и возвращает его индекс или "-1", если не находит подходящий.
Синтаксис
Функция имеет такой синтаксис:
Array.indexOf (search element, starting index)
где:
Если starting index отрицательный, то JS трактует это как смещение с конца массива: при starting index = “-1” будет проверен только последний элемент, при “-2” последние два и т.д.
Практика
Опробуем метод на практике. Запустим такой код и проверим результаты его работы:
let ExampleArray = [1,2,3,1,'5', null, false, NaN,3];
console.log("Позиция единицы", ExampleArray.indexOf(1) );
console.log("Позиция следующей единицы", ExampleArray.indexOf(1,2) );
console.log("Позиция тройки", ExampleArray.indexOf(3) );
console.log("Позиция тройки, если starting index отрицательный", ExampleArray.indexOf(3,-2) );
console.log("Позиция false", ExampleArray.indexOf(false) );
console.log("Позиция 5", ExampleArray.indexOf("5") );
console.log("Позиция NaN", ExampleArray.indexOf(NaN));
В результате работы этого кода мы получили такой вывод:
Позиция единицы 0
Позиция следующей единицы 3
Позиция тройки 2
Позиция тройки, если starting index отрицательный 8
Позиция false 6
Позиция 5 -1
Позиция NaN -1
indexOf
осуществляет поиск элемента в массиве слева направо и останавливает свою работу на первом совпавшем. Отчетливо это проявляется в примере с единицей. Для того, чтобы идти справа налево, используйте метод LastIndexOf
с аналогичным синтаксисом.
Для сравнения искомого и очередного объекта применяется строгое сравнение (===). При использовании строгого сравнения для разных типов данных, но с одинаковым значение, например 5, ‘5’ и “5” JavaScript даёт отрицательный результат, поэтому IndexOf
не нашел 5.
Также стоит помнить, что indexOf
некорректно обрабатывает NaN. Так что для работы с этим значением нужно применять остальные методы.
includes
не совсем проводит поиск заданного элемента в массиве, а проверяет, есть ли он там вообще. Работает он примерно также как и indexOf
. В конце работы includes
возвращает «True», если нашел искомый объект, и «False», если нет. Также includes
правильно обрабатывает NaN
Синтаксис
includes
имеет следующий синтаксис:
Array.includes (search element, starting index)
где:
Если starting index отрицательный, то JS трактует это как смещение с конца массива: при starting index = “-1” будет проверен только последний элемент, при “-2” последние два и т.д.
Практика
Немного изменим код из предыдущего примера и запустим его:
let Example = [1,2,3,1,'5', null, false,NaN, 3];
console.log("Наличие единицы", Example.includes(1) );
console.log("Наличие следующей единицы", Example.includes(1,2) );
console.log("Наличие тройки", Example.includes(3) );
console.log("Наличие тройки, если starting index отрицательный", Example.includes(3,-1) );
console.log("Наличие false", Example.includes(false) );
console.log("Наличие 5", Example.includes(5) );
console.log("Наличие NaN", Example.includes(NaN));
Вывод:
Наличие единицы true
Наличие следующей единицы true
Наличие тройки true
Наличие тройки, если starting index отрицательный true
Наличие false true
Наличие 5 false
Наличие NaN true
Для includes
отсутствует альтернативная функция, которая проводит поиск по массиву js справа налево, которая, в общем-то, и не очень актуальна.
Предположим, что нам нужно найти в массиве некий объект. Но мы хотим найти его не по значению, а по его свойству. Например, поиск числа в массиве со значением между 15 и 20. Как и прежде, мы можем воспользоваться перебором с помощью for
, но это не слишком удобно. Для поиска с определенным условием в JavaScript существует метод find
.
Синтаксис
Array.find(function(...){
//если элемент соответствует условиям (true), то функция возвращает его и прекращает работу;
//если ничего не найдено, то возвращает undefined
})
Практика
Как и в прошлых примерах, напишем небольшой код и опробуем метод:
let ExampleArray = ["Timeweb", 55555, "Cloud", "облачный провайдер", "буквы"];
console.log(ExampleArray.find(element => element.length == 5))
Вывод:
Cloud
В этом примере мы искали строки с длиной в 5 символов. Для числовых типов данных длина не определена, поэтому 55555 не подходит. find
находит первый элемент и возвращает его, поэтому «буквы» также не попали в результат работы нашей функции. Для того, чтобы найти несколько элементов, соответствующих некоторому условию, нужно использовать метод filter
.
Также не стоит забывать о методе findIndex
. Он возвращает индекс подходящего элемента. Или -1, если его нет. В остальном он работает точно также, как и find
.
find
ищет и возвращает первый попавшийся элемент, соответствующий условиям поиска. Для того, чтобы найти все такие элементы, необходимо использовать метод filter
. Результат этой функции — массив (если ничего не найдено, то он будет пустым).
Синтаксис
Array.find(function(...){
//если элемент соответствует условиям (true), то добавляем его к конечному результату и продолжаем перебор;
})
Практика
Представим следующую задачу: у нас есть список кубоидов (прямоугольных параллелепипедов) с длинами их граней и нам нужно вывести все кубоиды с определенным объемом. Напишем код, реализующий решение данной задачи:
let ExampleArray = [
[10, 15, 8],
[11, 12, 6],
[5, 20, 1],
[10, 10, 2],
[16,2, 4]
];
console.log(ExampleArray.filter(element=> element[0]*element[1]*element[2]>300))
Вывод:
[ [ 10, 15, 8 ],
[ 11, 12, 6 ] ]
В этом примере мы нашли прямоугольные параллелепипеды с объемом больше 300. В целом, метод filter
в JS позволяет реализовывать всевозможные условия для поиска.
Подготовили для вас выгодные тарифы на облачные серверы
В этой статье узнали о методах поиска в JavaScript и научились ими пользоваться. Все перечисленные методы — универсальные инструменты для разработчиков. Но, как и любые универсальные инструменты, они не всегда являются самыми производительными. Так, например, бинарный поиск будет куда эффективнее, чем find
и filter
.