javascript - объектов - поиск в массиве js

javascript - объектов - поиск в массиве js

Как проверить, содержит ли массив объект в JavaScript? (20)

ECMAScript 6 имеет элегантное предложение по поиску.

Метод find выполняет функцию обратного вызова один раз для каждого элемента, присутствующего в массиве, до тех пор, пока не найдет тот, где обратный вызов возвращает истинное значение. Если такой элемент найден, find немедленно возвращает значение этого элемента. В противном случае find возвращает undefined. callback вызывается только для индексов массива, которым присвоены значения; он не вызывается для индексов, которые были удалены или которые никогда не были присвоены значениям.

Функция поиска работает так.

Вы можете использовать это в ECMAScript 5 и ниже, определив функцию .

Каков наиболее сжатый и эффективный способ узнать, содержит ли массив JavaScript объект?

Это единственный способ, которым я это знаю:

Есть ли лучший и более сжатый способ сделать это?

Это очень тесно связано с вопросом о переполнении стека. Лучший способ найти элемент в массиве JavaScript? который адресует поиск объектов в массиве с помощью indexOf .

В ECMAScript 7 представлен array.includes(value) .

Его можно использовать следующим образом:

Он также принимает необязательный второй аргумент fromIndex :

В отличие от indexOf , который использует Strict Equality Comparison , includes сравнения с использованием алгоритма равенства SameValueZero . Это означает, что вы можете определить, содержит ли массив NaN :

Кроме того, в отличие от indexOf , indexOf не пропускает отсутствующие индексы:

В настоящее время он по-прежнему является черновиком, но может быть polyfill чтобы он работал на всех браузерах.

В то время как array.indexOf(x)!=-1 является наиболее кратким способом сделать это (и был поддержан браузерами не Internet Explorer более десятилетия . ), это не O (1), а скорее O ( N), что ужасно. Если ваш массив не изменится, вы можете преобразовать свой массив в хеш- table[x]!==undefined , а затем сделать table[x]!==undefined или ===undefined :

(К сожалению, в то время как вы можете создать Array.prototype.contains, чтобы «заморозить» массив и сохранить хэш-таблицу в this._cache в двух строках, это приведет к неправильным результатам, если вы захотите позже отредактировать свой массив. В JavaScript недостаточно крючков для позвольте вам сохранить это состояние, в отличие от Python, например.)

Верхние ответы предполагают примитивные типы, но если вы хотите узнать, содержит ли массив объект с некоторой чертой, Array.prototype.some() - очень изящное решение:

Самое приятное в том, что итерация прерывается после обнаружения элемента, поэтому сохраняются ненужные итерационные циклы.

Кроме того, он отлично вписывается в оператор if поскольку он возвращает логическое значение:

* Как отметил jamess в комментарии, на сегодняшний день, сентябрь 2018 года, Array.prototype.some() полностью поддерживается: таблица поддержки caniuse.com

Вы также можете использовать этот трюк:

Если вы используете JavaScript 1.6 или более поздней версии (Firefox 1.5 или новее), вы можете использовать Array.indexOf . В противном случае, я думаю, вы закончите с чем-то похожим на ваш исходный код.

Я знаю, что это не лучший способ, но, поскольку нет естественного способа сопоставления между объектами IComparable, я думаю, это так близко, что вы можете сравнить два объекта в массиве. Кроме того, расширение объекта Array может быть неразумным, но иногда это нормально (если вы знаете об этом и компромисс).

Используйте some функцию lodash.

Он лаконичен, точен и обладает большой поддержкой кросс-платформы.

Принятый ответ даже не соответствует требованиям.

Требования: рекомендуйте наиболее сжатый и эффективный способ узнать, содержит ли массив JavaScript объект.

Принятый ответ:

Моя рекомендация:

$ .inArray отлично подходит для определения, существует ли скалярное значение в массиве скаляров .

. но вопрос явно требует эффективного способа определить, содержится ли объект в массиве.

Чтобы обрабатывать как скаляры, так и объекты, вы можете сделать это:

Как уже упоминалось, вы можете использовать Array.indexOf , но он недоступен во всех браузерах. Вот код из https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf чтобы он работал в старых браузерах.

indexOf - последнее дополнение к стандарту ECMA-262; как таковой, он не может присутствовать во всех браузерах. Вы можете обойти это, вставив следующий код в начале ваших сценариев, позволяя использовать indexOf в реализациях, которые его не поддерживают. Этот алгоритм точно такой, который указан в ECMA-262, 5th edition, при условии, что Object, TypeError, Number, Math.floor, Math.abs и Math.max имеют свое первоначальное значение.

Мы используем этот фрагмент (работает с объектами, массивами, строками):

Использование:

Ниже приведена Array.indexOf JavaScript, совместимая с JavaScript 1.6 : Array.indexOf :

Размышляя о коробке на секунду, если вы делаете этот вызов много раз, гораздо эффективнее использовать ассоциативный массив, который будет выполнять поиск, используя хеш-функцию.

Расширение объекта JavaScript Array - действительно плохая идея, потому что вы вводите новые свойства (ваши собственные методы) for-in циклы for-in которые могут нарушать существующие скрипты. Несколько лет назад авторам библиотеки Prototype пришлось перестроить свою библиотечную реализацию, чтобы удалить именно такую ​​вещь.

Если вам не нужно беспокоиться о совместимости с другим JavaScript, запущенным на вашей странице, пойдите для этого, иначе я бы рекомендовал более неудобное, но более безопасное решение для самостоятельной работы.

Хорошо, вы можете просто оптимизировать свой код, чтобы получить результат! Есть много способов сделать это, что чище и лучше, но я просто хотел получить ваш шаблон и применить к нему с помощью JSON.stringify , просто просто сделайте что-то вроде этого в вашем случае:

Я использую следующее:

b - значение, a - массив. Он возвращает true или false :

indexOf более быстрая двунаправленная indexOf / lastIndexOf

В то время как новый метод array.includes(value) очень хорошо, поддержка в настоящий момент равна нулю.

Я долго думал о том, как заменить медленные функции indexOf / lastIndexOf.

Уже был найден исполнительный путь, глядя на верхние ответы. Из тех, что я выбрал, contains функцию, опубликованную @Damir Zekic, которая должна быть самой быстрой. Но в нем также говорится, что эталонные показатели с 2008 года и так устарели.

Я также предпочитаю, while закончили, но не по какой-то конкретной причине я закончил писать функцию с циклом for. Это может быть сделано и через некоторое while -- .

Мне было любопытно, если итерация была намного медленнее, если я проверяю обе стороны массива, делая это. По-видимому, нет, и поэтому эта функция примерно в два раза быстрее, чем верхние проголосовавшие. Очевидно, что он также быстрее, чем родной. Это в реальной среде, где вы никогда не знаете, находится ли значение, которое вы ищете, в начале или в конце массива.

Когда вы знаете, что просто нажали массив со значением, использование lastIndexOf остается, пожалуй, лучшим решением, но если вам нужно путешествовать по большим массивам, и результат может быть повсюду, это может быть надежным решением для ускорения работы.

Двунаправленный индексOf / lastIndexOf

Тест производительности

В качестве теста я создал массив с 100 тыс. Записей.

Три запроса: в начале, в середине и в конце массива.

Надеюсь, вы также найдете это интересным и испытаете производительность.

Примечание. Как вы можете видеть, я слегка изменил функцию contains чтобы отразить вывод indexOf & lastIndexOf (так что в основном true с index и false с -1 ). Это не должно навредить ему.

Вариант прототипа массива

Функция также может быть легко изменена, чтобы возвращать true или false или даже объект, строку или что-то еще.

Как это возможно?

Я думаю, что простой расчет для получения отраженного индекса в массиве настолько прост, что он в два раза быстрее, чем выполнение фактической итерации цикла.

Вот сложный пример, выполняющий три проверки на итерацию, но это возможно только при более длительном вычислении, которое вызывает замедление кода.

📎📎📎📎📎📎📎📎📎📎