Семь различных способов проверить наличие элемента в массиве с помощью тестов производительности
Когда дело доходит до определения наличия элемента в массиве в JavaScript, есть несколько разных способов. И это вызывает следующий вопрос: что использовать и что работает лучше. В этой статье я собираюсь перечислить все семь различных способов вместе с некоторыми тестовыми запусками, чтобы увидеть, какой из них окажется в верхней части списка.
Семь разных способов:
Давайте сначала подробно обсудим каждый метод.
- Метод Array.indexOf
Array.indexOf
принимает элемент и необязательный start-from-index. Когда передается start-from-index, алгоритм ищет элемент, начинающийся с этого индекса. Метод возвращает индекс первого вхождения элемента или -1
, если ничего не найдено.
2. Встроенный цикл for
Пройдитесь по циклу, пока не найдем желаемый элемент, увеличивая индекс до тех пор, пока индекс не станет меньше длины массива. В любом случае, когда элемент будет найден, мы установим нашу локальную переменную isPresent
на true
и прервем цикл.
3. for… of цикла
Из документов https://developer.mozilla.org/:
Оператор
for...of
создает цикл, перебирающий итерируемые объекты, включая: встроенныеString
,Array
, объекты, подобные массиву.
Для простоты мы будем придерживаться варианта использования Array.
Как и в случае с native-for-loop, мы можем выйти из цикла, как только обнаружим, что элемент buy нарушает цикл.
4. Array.some
Array.some()
принимает функцию callback
и выполняет функцию один раз для каждого элемента, присутствующего в массиве, пока не найдет тот, где callback
вернет истинное значение.
5. Array.includes
Метод Array.includes принимает элемент и необязательное начало с индекса, если мы хотим искать по определенному индексу и возвращает логическое значение.
6. Array.find
Метод find()
возвращает значение первого элемента в предоставленном массиве, который удовлетворяет предоставленной функции обратного вызова. Если элемент не найден, возвращается undefined
.
7. Array.findIndex
Array.findIndex
принимает функцию обратного вызова, которую он выполняет для каждого элемента, пока не найдет элемент, который возвращает истинное значение при выполнении обратного вызова. Подобно Array.indexOf
, он возвращает -1
, если элемент не найден.
Теперь мы рассмотрели все методы определения существования элемента. Давайте теперь проведем несколько тестов, чтобы увидеть, как работает каждый из этих методов.
Тестовые примеры:
Давайте создадим массив с одним миллионом записей, начиная со значений от 1 до 1000000.
let array = new Array(1000000).fill(0).map((_v, i) => i + 1);
Вот наши четыре тестовых случая:
const testCases = [1, 500000, 1000000, 1000010];
Массив testCases
включает первое значение в array
, среднее значение (500000), последнее значение (1000000) и несуществующее значение.
Давайте создадим служебную функцию, которая принимает функцию обратного вызова для выполнения этих тестов для каждого метода.
Вышеупомянутая функция util принимает функцию обратного вызова и имя функции имени в качестве входных данных и вызывает функцию обратного вызова с разными входами, отслеживая и обновляя время, затрачиваемое для каждого сценария в объекте result
. После запуска всех тестовых примеров среднее затраченное время рассчитывается и добавляется к объекту с Average
в качестве имени свойства. Простой пример использования этого метода также добавлен на картинке выше. Точно так же мы можем вызывать метод util с другими типами методов, перечисленных выше.
Вот полный код для этого
Этот тестовый пример был запущен в инструментах chrome dev на машине с Windows. А вот показатели производительности для всех случаев
Если посмотреть на среднее время, кажется, что Array.indexOf
более эффективен для примитивных случаев.
Вывод:
Есть много разных способов проверить наличие элемента в массиве.
Для примитивов Array.indexOf
, Array.includes
кажутся подходящими кандидатами, поскольку оба они занимают ~ 1 мс для разных тестовых случаев с массивом из 1 мельничных элементов.
Спасибо за прочтение! Следуйте за мной, чтобы увидеть больше интересных статей.