Каков наиболее краткий и эффективный способ узнать, содержит ли массив JavaScript значение?
Это единственный известный мне способ сделать это:
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
Есть ли лучший и более лаконичный способ сделать это?
многие ответили, что Array # indexOf - ваш лучший выбор. Но если вы хотите что-то, что может быть правильно преобразовано в логическое значение, используйте это: ~[1,2,3].indexOf(4) вернет 0, что будет оценено как ложь, тогда как ~[1,2,3].indexOf(3) вернет -3, что будет оцениваться как истина.
~ - это не то, что вы хотите использовать для преобразования в логическое значение, для этого вам нужен !. Но в этом случае вы хотите проверить равенство с -1, так как функция может закончить return [1,2,3].indexOf(3) === -1;~ не является двоичным, она будет инвертировать каждый бит значения индивидуально.
IE9 поддерживает indexOf() согласно w3schools.com/jsref/jsref_indexof_array.asp. Если в более старом браузере лучше всего определить prototype для функции indexOf(), как указано в Array.indexOf в Internet Explorer
@Iordvlad [1,2,3].indexOf(4) на самом деле будет возврат -1. Как указал @mcfedr, ~ - это побитовый оператор НЕ, см. ES5 11.4.8. Дело в том, что поскольку двоичное представление -1 состоит только из единиц, его дополнением является 0, который оценивается как ложный. Дополнение любого другого числа будет отличным от нуля, следовательно, истинным. Итак, ~ отлично работает и часто используется вместе с indexOf.
Название вводит в заблуждение. Где [[1,2],[3,4]].includes([3,4])?
@brad, когда я впервые прочитал ваш вопрос, я не мог понять вашу идею, объект здесь - это объект javascript или примитивное значение. Допустим, у меня есть массив: const arr = [1, 2, 3, { foo: 1}];. И arr.includes(1) // true, но arr.includes({ foo: 1 }) //false
some.
let arr = ['apple','banana', 1, 2, 4] if (!arr.includes('banana') ) console.info('No') else console.info('Yes')


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы используете JavaScript 1.6 или новее (Firefox 1.5 или новее), вы можете использовать Array.indexOf. В противном случае, я думаю, вы получите что-то похожее на исходный код.
Может быть, indexOf, но это «расширение JavaScript стандарта ECMA-262; как таковое оно может отсутствовать в других реализациях стандарта».
Пример:
[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1
AFAICS Microsoft предлагает нет какую-то альтернативу к этому, но вы можете добавить аналогичные функции к массивам в Internet Explorer (и других браузерах, которые не поддерживают indexOf), если хотите, как быстрый поиск в Google показывает (например, Вот этот).
Фактически, есть пример реализации расширения indexOf для браузеров, которые его не поддерживают, на странице developer.mozilla.org, на которую вы ссылаетесь.
на самом деле, если вы добавите indexof к прототипу Array для браузеров, которые его не поддерживают (например, IE7), они также попытаются перебрать эту функцию при циклическом обходе элементов в массиве. противный.
применимо ли это для проверки объекта? я не думаю, что это работает в случае объекта
Обновление от 2019 года: этот ответ относится к 2008 году (11 лет!) И не актуален для современного использования JS. Обещанное улучшение производительности было основано на тестах, проведенных в браузерах того времени. Это может не иметь отношения к современным контекстам выполнения JS. Если вам нужно простое решение, поищите другие ответы. Если вам нужна лучшая производительность, протестируйте себя в соответствующих средах выполнения.
Как говорили другие, итерация по массиву, вероятно, лучший способ, но было доказано, что убывающий цикл while - это самый быстрый способ итерации в JavaScript. Поэтому вы можете переписать свой код следующим образом:
function contains(a, obj) {
var i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
}
Конечно, вы также можете расширить прототип массива:
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
А теперь вы можете просто использовать следующее:
alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
Но будьте осторожны: stackoverflow.com/questions/237104/javascript-array-contains obj /…
«Проверено» - сильное слово. Движки JS постоянно улучшаются, а время выполнения, измеренное 3 года назад, ужасно устарело.
@orip отличный момент. Но даже в этом случае для самого медленного браузера это все еще актуально. Для современных браузеров разница либо незначительна, либо несущественна (поскольку они уже поддерживают indexOf). Я обновил ответ, спасибо.
@ Дамир - согласен. Возможно, измените образец, чтобы использовать indexOf, если он доступен, чтобы люди, слепо копирующие этот код, получили максимальную производительность.
расширение массива таким образом вызовет еще одну проблему. если вы используете for (x в myArray), он также будет циклически перебирать методы прототипа, поэтому вам нужно теперь проверить, является ли каждый x свойством. Я ищу прямо сейчас, чтобы увидеть, есть ли способ исправить это, не переделывая все мои for (in).
вам следует использовать i in obj && ... === ..., потому что в случае разреженных массивов var arr=[];arr[4] = "d"; он ошибочно вернет true при поиске undefined
+1 за предоставление ССЫЛКИ на доказательство времени итерации ... откровенные откровения в отношении цикла по элементам HTML ...
@cbmeeks да, уход определенно нужен. Вероятно, это был случай выполнения for (o in array), чего не следует делать при циклическом просмотре массива в целом ...
Лучший способ сделать это - проверить, если [1, 2, 3] .indexOf (1)> -1
Ваша функция contains работает во всех старых и новых браузерах?
что prototype () делает в js? используется ли он для добавления какого-либо расширения к любому классу или объекту извне?
В nodejs (v7.4.0) на моей 64-битной машине с Windows 7 поиск 1 в массиве с 10M нулями; цикл while занимает около 240+ мс, цикл for (также обратный отсчет) занимает около 220 мс, а метод indexOf занимает около 20 мс. Если я заполняю этот массив некоторыми увеличивающимися числами (от 0 до 10M-1) и ищу -1, цикл while становится быстрее примерно в 4 раза, цикл for становится быстрее примерно в 8 раз, а indexOf занимает примерно на 25-50% больше времени. Цвет меня удивил.
Этот ответ должен быть отклонен или удален, поскольку это худшее решение для этой даты (в то время оно было достаточно хорошим).
@ DamirZekić, я не думаю, что содержит метод в JS, включает правильный синтаксис здесь
Заявления о производительности при таком подходе сомнительны. Во-первых, его обратное направление может давать ложные срабатывания в тестах, которые смещаются в сторону элементов в конце массива. С другой стороны, запуск теста в Perflink показывает, что этот код работает примерно на 9% от скорости includes (для элемента около середины массива), тогда как идентичный тест в jsBench показывает, что он приближается к includes или даже иногда опережает его. (Эти тесты проводились несколько раз для одного и того же браузера, версии браузера и компьютера.) Это странное несоответствие.
Вот реализация Array.indexOfСовместимость с JavaScript 1.6:
if (!Array.indexOf) {
Array.indexOf = [].indexOf ?
function(arr, obj, from) {
return arr.indexOf(obj, from);
} :
function(arr, obj, from) { // (for IE6)
var l = arr.length,
i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
i = i < 0 ? 0 : i;
for (; i < l; i++) {
if (i in arr && arr[i] === obj) {
return i;
}
}
return -1;
};
}
Выглядит великолепно, но немного сбивает с толку: * Разве тесты в строках 1 и 3 не эквивалентны? * Не лучше ли протестировать прототип и при необходимости добавить функцию в Array.prototype?
Они не эквивалентны. [].indexOf - это сокращение от Array.prototype.indexOf. Мы, параноидально защищающиеся Javascript-программисты, любой ценой избегаем расширения собственных прототипов.
Разве [].indexOf не создает новый массив, а затем обращается к indexOf, в то время как Array.prototype.indexOf просто обращается к прототипу напрямую?
@alex да [].indexOf === Array.prototype.indexOf (попробуйте в FireBug), но наоборот [].indexOf !== Array.indexOf.
Расширение объекта JavaScript Array - действительно плохая идея, потому что вы вводите новые свойства (свои собственные методы) в циклы for-in, которые могут нарушить существующие сценарии. Несколько лет назад авторам библиотеки Прототип пришлось перепроектировать реализацию своей библиотеки, чтобы удалить именно такие вещи.
Если вам не нужно беспокоиться о совместимости с другим JavaScript, работающим на вашей странице, сделайте это, в противном случае я бы порекомендовал более неудобное, но более безопасное автономное функциональное решение.
Я не согласен. Именно по этой причине для массивов не следует использовать циклы For-in. Использование циклов for-in сломается при использовании одной из популярных библиотек js.
Будет ли это считаться исправлением обезьяны? lol Некоторым это нравится.
Вот как Прототип делает это:
/**
* Array#indexOf(item[, offset = 0]) -> Number
* - item (?): A value that may or may not be in the array.
* - offset (Number): The number of initial items to skip before beginning the
* search.
*
* Returns the position of the first occurrence of `item` within the array — or
* `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
i || (i = 0);
var length = this.length;
if (i < 0) i = length + i;
for (; i < length; i++)
if (this[i] === item) return i;
return -1;
}
Также см. здесь, чтобы узнать, как они его подключают.
В современных браузерах есть Array#includes, который делает точно, и широко поддерживается всеми, кроме IE:
console.info(['joe', 'jane', 'mary'].includes('jane')); //trueВы также можете использовать Array#indexOf, который менее прямой, но не требует полифиллов для устаревших браузеров.
console.info(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //trueМногие фреймворки также предлагают похожие методы:
$.inArray(value, array, [fromIndex])_.contains(array, value) (также называемый _.include и _.includes)dojo.indexOf(array, value, [fromIndex, findLast])array.indexOf(value)array.indexOf(value)findValue(array, value)array.indexOf(value)Ext.Array.contains(array, value)_.includes(array, value, [from]) (это _.contains до 4.0.0)R.includes(value, array)Обратите внимание, что некоторые платформы реализуют это как функцию, а другие добавляют функцию к прототипу массива.
В MooTools также есть Array.contains, который возвращает логическое значение, что здесь звучит как настоящий вопрос.
прототип также имеет Array.include, который возвращает логическое значение
Если вы используете хороший браузер, вы можете просто использовать array.indexOf(object) != -1.
@ user102008: MDN не содержит никаких ссылок на Array.include (Справочник по массиву MDN - я искал, какая версия JS была в нем.) Где вы видели ссылку на этот метод?
Кроме того, не используйте только indexOf в качестве условия, потому что первый элемент вернет 0 и будет оценен как ложный.
inArray - ужасное имя для функции, возвращающей индекс элемента, и -1, если он не существует. Я ожидал, что будет возвращено логическое значение.
var inArray = function(a,b,c,d){for(c in b)d|=b[c]===a;return!!d }убрать подчеркивание включил?
@jcolebrand Я обновил ответ. include все еще существует, но в документации указан как псевдоним для contains
@Tim, я думаю, он возвращает -1, чтобы свести на нет вероятность того, что 0 будет принят как ложь
Я думаю, что кто-то упомянул, что вы можете получить около 0, которое будет оценено как ложное, используя оператор ===, хотя бы мимоходом.
Я думал, что дротик - это родной язык. Он действительно компилируется в JS? Обновлено: о, его можно скомпилировать в JS, хотя он лучше всего работает в браузере, созданном для его запуска.
@IulianOnofrei: Нет, 2 in [1,2,3] == true, но 5 in [3,4,5] == false. Почему? Поскольку массивы в сценариях JavaScripts ведут себя так же, как обычные объекты, 2 in array фактически означает только то, что array[2] определен. Имейте в виду, что это поведение все еще потенциально полезно, поскольку массивы JavaScript могут быть разреженными: 2 in [1,2,,3] == false
Вы также должны проверить это предложение: github.com/tc39/Array.prototype.includes Также это для различных способов использования Array.prototype.indexOf(): codereview.stackexchange.com/questions/13941/…
Почему бы не привести в ответ пример? if ($.inArray(value, array)) > -1 { // found value in array }
сейчас 2016, и я все еще не могу правильно использовать .include и .indexOf для типа non primitive.
Но ничего из этого не будет работать для массива сложного типа? он работает со строками, числами и всем, что abt var arr = [{"id": "1", "name": "Joe"}, {"id": "2", "name": "Smith"} ]; var obj = {"id": "1", "name": "Joe"}; arr.includes (obj);
array.includes(foo) не поддерживает объекты. Я не уверен, почему это принятый ответ, потому что он был задан Как проверить, включает ли массив объект в JavaScript?"широко" вводит в заблуждение, поскольку IE 11 его не поддерживает
Мне просто нужно запомнить indexOf для стендов Array и String :) на всякий случай.
как проверить ключ и значение с помощью включения?
возможно, используйте IndexOf ^^
у этого ответа так много голосов, но вопрос касается объектов в массивах, с которыми это не работает.
@Stophface @Emobe Как это может быть неправильный ответ? В вопросе задавались способы сделать то же самое, что и в предоставленном коде. И Array#includes делает именно то, что делает код в вопросе.
Отличный ответ. ПРИМЕЧАНИЕ. includes (и indexOf) НЕ преобразовывают тип. Вам нужно будет сделать это в коде, я полагаю, console.info(['joe', 'jane', 'mary', 46].includes(Number('46')));
Если подумать на секунду нестандартно, если вы делаете этот вызов много раз, гораздо эффективнее использовать ассоциативный массив a Map для поиска с использованием хэш-функции.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
Хотя это, очевидно, полезно для многих, было бы лучше, если бы был добавлен фрагмент кода.
Еще один вариант
// usage: if ( ['a','b','c','d'].contains('b') ) { ... }
Array.prototype.contains = function(value){
for (var key in this)
if (this[key] === value) return true;
return false;
}
Будьте осторожны, поскольку перегрузка объектов массива javascript пользовательскими методами может нарушить поведение других сценариев JavaScript, вызывая неожиданное поведение.
Но будьте осторожны: stackoverflow.com/questions/237104/javascript-array-contains obj /…
Пожалуйста, не используйте цикл for in для итерации по массиву - циклы for in следует использовать только для объектов.
почему это так плохо
пожалуйста, не отменяйте встроенные developers.google.com/web/updates/2018/03/smooshgate
Если вы неоднократно проверяете наличие объекта в массиве, вам, возможно, следует изучить
contains(a, obj).Или, если возможно, полностью прекратите использование массива и вместо этого используйте объект в качестве словаря, как предлагали MattMcKnight и ninjagecko.
Буквально:
(с использованием Firefox v3.6, с оговорками for-in, как отмечалось ранее
(ОДНАКО приведенное ниже использование может поддерживать for-in именно для этой цели! То есть перечисление элементов массива, которые ДЕЙСТВИТЕЛЬНО существуют через индекс свойства (ОДНАКО, в частности, свойство массива length НЕ перечисляется в списке свойств for-in!).).
(Перетащите следующие полные URI для немедленного тестирования браузера.)
function ObjInRA(ra){var has=false; for(i in ra){has=true; break;} return has;}
function check(ra){
return ['There is ',ObjInRA(ra)?'an':'NO',' object in [',ra,'].'].join('')
}
alert([
check([{}]), check([]), check([,2,3]),
check(['']), '\t (a null string)', check([,,,])
].join('\n'));
который отображает:
There is an object in [[object Object]].
There is NO object in [].
There is an object in [,2,3].
There is an object in [].
(a null string)
There is NO object in [,,].
Морщины: если вы ищете "конкретный" объект, обратите внимание:
JavaScript: alert({}! = {}); alert({}!= = {});
И поэтому:
obj = {prop:"value"};
ra1 = [obj];
ra2 = [{prop:"value"}];
alert(ra1[0] == obj);
alert(ra2[0] == obj);
Часто считается, что ra2 «содержит» obj как буквальную сущность {prop:"value"}.
Очень грубое, рудиментарное, наивное (как в коде требует повышения квалификации) решение:
obj = {prop:"value"}; ra2=[{prop:"value"}];
alert(
ra2 . toSource() . indexOf( obj.toSource().match(/^.(.*).$/)[1] ) != -1 ?
'found' :
'missing' );
См. Ссылку: Поиск объектов в массивах JavaScript.
Использовать:
Array.prototype.contains = function(x){
var retVal = -1;
// x is a primitive type
if (["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}
// x is a function
else if (typeof x = = "function") for(var ix in this){
if ((this[ix]+"")==(x+"")) retVal = ix;
}
//x is an object...
else {
var sx=JSON.stringify(x);
for(var ix in this){
if (typeof this[ix] = = "object" && JSON.stringify(this[ix])==sx) retVal = ix;
}
}
//Return False if -1 else number if numeric otherwise string
return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
}
Я знаю, что это не лучший способ, но, поскольку нет собственного IComparable способа взаимодействия между объектами, я думаю, это максимально близко для сравнения двух объектов в массиве. Кроме того, расширение объекта Array может быть неразумным решением, но иногда это нормально (если вы знаете об этом и о компромиссе).
Позднее примечание: это не работает, скажем, с contains([{ a: 1, b: 2 }], { b: 2, a: 1 }), потому что строковые объекты поддерживают порядок свойств.
Допустим, вы определили такой массив:
const array = [1, 2, 3, 4]
Ниже приведены три способа проверить, есть ли там 3. Все они возвращают либо true, либо false.
array.includes(3) // true
// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true
const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true
Он возвращает истину, если "b" находится в массиве "a" ... Я не знаю, как еще это объяснить ...
Я не понимаю "!! ~". И я думаю, что это не сработает в IE8, потому что IE8 не поддерживает indexOf () для объекта Array.
«~» - это оператор, который увеличивает, инвертирует и вычитает 1 из числа. indexOf возвращает -1 в случае неудачи, поэтому "~" превращает -1 в "0". с использованием "!!" превращает числа в булевы (!! 0 === false)
Круто, но серьезно для простоты y не просто a.indexOf (b)> - 1, так как "> -1" .length === "!! ~" .length
Я бы назвал незнание эффектов логических операторов непрофессиональным. Но я согласен с ценностью читаемого кода, я бы обязательно заключил это в четко обозначенную функцию. И это именно то, что делают большинство основных JS-фреймворков.
Хотя array.indexOf(x)!=-1 - самый лаконичный способ сделать это (и уже более десяти лет поддерживается браузерами, не относящимися к Internet Explorer ...), это не O (1), а скорее O (N), что ужасно. Если ваш массив не будет изменяться, вы можете преобразовать его в хеш-таблицу, а затем выполните table[x]!==undefined или ===undefined:
Array.prototype.toTable = function() {
var t = {};
this.forEach(function(x){t[x]=true});
return t;
}
Демо:
var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})
(К сожалению, хотя вы можете создать Array.prototype.contains, чтобы «заморозить» массив и сохранить хеш-таблицу в this._cache в две строки, это приведет к неправильным результатам, если вы решите изменить свой массив позже. У JavaScript недостаточно ловушек для пусть вы сохраните это состояние, в отличие, например, от Python.)
function inArray(elem,array)
{
var len = array.length;
for(var i = 0 ; i < len;i++)
{
if (array[i] == elem){return i;}
}
return -1;
}
Возвращает индекс массива, если найден, или -1, если не найден
Похожая вещь: находит первый элемент с помощью "лямбды поиска":
Array.prototype.find = function(search_lambda) {
return this[this.map(search_lambda).indexOf(true)];
};
Использование:
[1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })
=> 4
То же самое в coffeescript:
Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]
Это, безусловно, гораздо более гибкий подход, чем многие другие подходы. Если прототип не устраивает, можно рассмотреть что-то вроде var positionIf = function (предикат, последовательность) {return sequence.map (predicate) .indexOf (true);};
Более эффективный способ реализовать этот метод - использовать цикл и прекратить применение search_lambda, как только что-то будет найдено.
Как уже упоминалось, вы можете использовать Array.indexOf, но он доступен не во всех браузерах. Вот код из https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf, чтобы он работал так же в старых браузерах.
indexOf is a recent addition to the ECMA-262 standard; as such it may not be present in all browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing use of indexOf in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object, TypeError, Number, Math.floor, Math.abs, and Math.max have their original value.
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
Я просмотрел отправленные ответы и понял, что они применимы только в том случае, если вы ищете объект по ссылке. Простой линейный поиск со сравнением эталонных объектов.
Но допустим, у вас нет ссылки на объект, как вы найдете правильный объект в массиве? Вам придется идти линейно и глубоко сравнивать каждый объект. Представьте, что список слишком велик, а объекты в нем очень большие и содержат большие фрагменты текста. Производительность резко падает с увеличением количества и размера элементов в массиве.
Вы можете структурировать объекты и поместить их в собственную хеш-таблицу, но тогда у вас будет избыточность данных, запомнив эти ключи, потому что JavaScript хранит их для 'for i in obj', и вы хотите только проверить, существует ли объект или нет, то есть , у тебя есть ключ.
Я некоторое время думал об этом, создавая валидатор схемы JSON, и разработал простую оболочку для собственной хэш-таблицы, похожую на реализацию единственной хеш-таблицы, с некоторыми исключениями оптимизации, которые я оставил для работы с собственной хеш-таблицей. Нужен только тест производительности ... Все подробности и код можно найти в моем блоге: http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/ Я скоро опубликую результаты тестов.
Полное решение работает так:
var a = {'a':1,
'b':{'c':[1,2,[3,45],4,5],
'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
'u':'lol'},
'e':2};
var b = {'a':1,
'b':{'c':[2,3,[1]],
'd':{'q':3,'b':{'b':3}}},
'e':2};
var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init
hc.put({a:1, b:1});
hc.put({b:1, a:1});
hc.put(true);
hc.put('true');
hc.put(a);
hc.put(c);
hc.put(d);
console.info(hc.exists('true'));
console.info(hc.exists(a));
console.info(hc.exists(c));
console.info(hc.exists({b:1, a:1}));
hc.remove(a);
console.info(hc.exists(c));
Использовать:
function isInArray(array, search)
{
return array.indexOf(search) >= 0;
}
// Usage
if (isInArray(my_array, "my_value"))
{
//...
}
x ? true : false обычно избыточен. Это здесь.
@minitech Почему вы говорите, что это лишнее?
array.indexOf(search) >= 0 уже является логическим. Просто return array.indexOf(search) >= 0.
@minitech ну спасибо! На самом деле я не знал, что такую конструкцию можно вернуть. TIL что-то новое.
Буквально любая конструкция в javascript может быть возвращена
Использовать:
var myArray = ['yellow', 'orange', 'red'] ;
alert(!!~myArray.indexOf('red')); //true
Чтобы точно знать, что делает tilde~ на этом этапе, обратитесь к этому вопросу Что делает тильда, когда она предшествует выражению?.
Это уже было опубликовано полтора года назад, повторять не нужно.
На самом деле он не был опубликован. Не как ответ, а как комментарий к ответу, да и то не ясно и лаконично. Спасибо за публикацию, Мина Габриэль.
В ECMAScript 6 есть элегантное предложение по поиску.
The find method executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, find immediately returns the value of that element. Otherwise, find returns undefined. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
Вот Документация MDN по этому поводу.
Функция поиска работает следующим образом.
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.info( [4, 6, 8, 12].find(isPrime) ); // Undefined, not found
console.info( [4, 5, 8, 12].find(isPrime) ); // 5
Вы можете использовать это в ECMAScript 5 и ниже с помощью определение функции.
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
enumerable: false,
configurable: true,
writable: true,
value: function(predicate) {
if (this == null) {
throw new TypeError('Array.prototype.find called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
if (i in list) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return value;
}
}
}
return undefined;
}
});
}
Теперь это стандарт: ecma-international.org/ecma-262/6.0/#sec-array.prototype.fin d
Я использую следующее:
Array.prototype.contains = function (v) {
return this.indexOf(v) > -1;
}
var a = [ 'foo', 'bar' ];
a.contains('foo'); // true
a.contains('fox'); // false
Первые ответы предполагают примитивные типы, но если вы хотите узнать, содержит ли массив объект с некоторой характеристикой, Array.prototype.some () - элегантное решение:
const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]
items.some(item => item.a === '3') // returns true
items.some(item => item.a === '4') // returns false
Приятно то, что итерация прерывается, как только элемент найден, поэтому ненужные циклы итераций сокращаются.
Кроме того, он хорошо вписывается в оператор if, поскольку возвращает логическое значение:
if (items.some(item => item.a === '3')) {
// do something
}
* Как указал Джеймс в комментарии, на момент этого ответа, сентябрь 2018 г., Array.prototype.some() полностью поддерживается: таблица поддержки caniuse.com
На сегодняшний день, сентябрь 2018 г., Array.prototype.some () полностью поддерживается: таблица поддержки caniuse.com
Работа в Node> = 8.10 для AWS Node.js Lambda, так что это здорово. Очень чистое и простое решение! ??
@jamess Возможно, он хорошо поддерживается, но помните, что Arrow functions в этом примере не так хорошо поддерживается. Подробнее см. Здесь: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Есть короткое замыкание? Или он перебирает весь массив, даже если он нашел значение?
@DouglasGaskell прерывает найденную итерацию (упоминается в ответе)
Мы используем этот сниппет (работает с объектами, массивами, строками):
/*
* @function
* @name Object.prototype.inArray
* @description Extend Object prototype within inArray function
*
* @param {mix} needle - Search-able needle
* @param {bool} searchInKey - Search needle in keys?
*
*/
Object.defineProperty(Object.prototype, 'inArray',{
value: function(needle, searchInKey){
var object = this;
if ( Object.prototype.toString.call(needle) === '[object Object]' ||
Object.prototype.toString.call(needle) === '[object Array]'){
needle = JSON.stringify(needle);
}
return Object.keys(object).some(function(key){
var value = object[key];
if ( Object.prototype.toString.call(value) === '[object Object]' ||
Object.prototype.toString.call(value) === '[object Array]'){
value = JSON.stringify(value);
}
if (searchInKey){
if (value === needle || key === needle){
return true;
}
}else{
if (value === needle){
return true;
}
}
});
},
writable: true,
configurable: true,
enumerable: false
});
Использование:
var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first"); //true
a.inArray("foo"); //false
a.inArray("foo", true); //true - search by keys
a.inArray({three: "third"}); //true
var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one"); //true
b.inArray('foo'); //false
b.inArray({foo: 'val'}) //true
b.inArray("{foo: 'val'}") //false
var c = "String";
c.inArray("S"); //true
c.inArray("s"); //false
c.inArray("2", true); //true
c.inArray("20", true); //false
function contains(a, obj) {
return a.some(function(element){return element == obj;})
}
Array.prototype.some () был добавлен в стандарт ECMA-262 в 5-м издании
при использовании es6 его можно сократить до contains = (a, obj) => a.some((element) => element === obj))
Даже IE9 поддерживает Array.prototype.some () начиная с ECMAScript 5.
ECMAScript 7 вводит Array.prototype.includes.
Его можно использовать так:
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
Он также принимает необязательный второй аргумент fromIndex:
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
В отличие от indexOf, который использует Строгое сравнение равенства, includes сравнивает с использованием алгоритма равенства SameValueZero. Это означает, что вы можете определить, включает ли массив NaN:
[1, 2, NaN].includes(NaN); // true
Также в отличие от indexOf, includes не пропускает отсутствующие индексы:
new Array(5).includes(undefined); // true
В настоящее время это все еще черновик, но может быть полифиллированный, чтобы он работал во всех браузерах.
Не поддерживается для IE и Microsfot Edge (2015) (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)
Также актуален Таблица совместимости ES7 (похоже, Chrome теперь поддерживает его)
применимо ли это для проверки объекта? я не думаю, что это работает в случае объекта
Один лайнер:
function contains(arr, x) {
return arr.filter(function(elem) { return elem == x }).length > 0;
}
array.filter(e=>e==x).length > 0 эквивалентен array.some(e=>e==x), но some более эффективен
Надеемся, более быстрая двунаправленная альтернатива indexOf / lastIndexOf
Хотя новый метод включает в себя очень хорош, поддержка на данный момент практически нулевая.
Я давно думал о том, как заменить медленные функции indexOf / lastIndexOf.
Эффективный способ уже найден, глядя на самые популярные ответы. Из них я выбрал функцию contains, опубликованную @Damir Zekic, которая должна быть самой быстрой. Но в нем также указано, что эталоны датированы 2008 годом и поэтому устарели.
Я также предпочитаю whilefor, но не по какой-то конкретной причине я закончил писать функцию с помощью цикла for. Это также можно было сделать с помощью while --.
Мне было любопытно, будет ли итерация намного медленнее, если я при этом проверю обе стороны массива. По-видимому, нет, и поэтому эта функция примерно в два раза быстрее, чем у самых популярных. Очевидно, он также быстрее родного. Это в реальной среде, где вы никогда не узнаете, находится ли искомое значение в начале или в конце массива.
Когда вы знаете, что только что отправили массив со значением, использование lastIndexOf, вероятно, остается лучшим решением, но если вам нужно перемещаться по большим массивам, и результат может быть везде, это может быть надежным решением для ускорения работы.
Двунаправленный indexOf / lastIndexOf
function bidirectionalIndexOf(a, b, c, d, e){
for(c=a.length,d=c*1; c--; ){
if (a[c]==b) return c; //or this[c]===b
if (a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
}
return -1
}
//Usage
bidirectionalIndexOf(array,'value');
http://jsperf.com/bidirectionalindexof
В качестве теста я создал массив из 100 тыс. Записей.
Три запроса: в начале, в середине и в конце массива.
Я надеюсь, что вы тоже найдете это интересным и протестируете производительность.
Примечание. Как вы можете видеть, я немного изменил функцию contains, чтобы отразить вывод indexOf и lastIndexOf (в основном true с index и false с -1). Это не должно ему навредить.
Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
for(c=this.length,d=c*1; c--; ){
if (this[c]==b) return c; //or this[c]===b
if (this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
}
return -1
},writable:false, enumerable:false});
// Usage
array.bidirectionalIndexOf('value');
Функцию также можно легко изменить, чтобы она возвращала истину или ложь или даже объект, строку или что-то еще.
А вот вариант while:
function bidirectionalIndexOf(a, b, c, d){
c=a.length; d=c-1;
while(c--){
if (b===a[c]) return c;
if (b===a[d-c]) return d-c;
}
return c
}
// Usage
bidirectionalIndexOf(array,'value');
Я думаю, что простой расчет для получения отраженного индекса в массиве настолько прост, что это в два раза быстрее, чем выполнение реальной итерации цикла.
Вот сложный пример, выполняющий три проверки на итерацию, но это возможно только при более длительном вычислении, которое вызывает замедление кода.
Используйте функцию lodash немного.
Он краткий, точный и имеет отличную кроссплатформенную поддержку.
Принятый ответ даже не соответствует требованиям.
Требования: Рекомендуется наиболее краткий и эффективный способ узнать, содержит ли массив JavaScript объект.
Принятый ответ:
$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1
Моя рекомендация:
_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true
Заметки:
$ .inArray отлично подходит для определения, существует ли значение скаляр в массиве скаляров ...
$.inArray(2, [1,2])
> 1
... но вопрос явно требует эффективного способа определить, содержится ли объект в массиве.
Чтобы обрабатывать как скаляры, так и объекты, вы можете сделать это:
(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)
Можно использовать Набор, у которого есть метод has ():
function contains(arr, obj) {
var proxy = new Set(arr);
if (proxy.has(obj))
return true;
else
return false;
}
var arr = ['Happy', 'New', 'Year'];
console.info(contains(arr, 'Happy'));Я думаю, что return proxy.has(obj) намного чище, чем две строки с выражением if-else здесь
function contains(arr, obj) { return new Set(arr).has(obj); }Отнюдь не лучший, но я просто проявлял творческий подход и дополнял репертуар.
Object.defineProperty(Array.prototype, 'exists', {
value: function(element, index) {
var index = index || 0
return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
}
})
// Outputs 1
console.info(['one', 'two'].exists('two'));
// Outputs -1
console.info(['one', 'two'].exists('three'));
console.info(['one', 'two', 'three', 'four'].exists('four'));Что использовать, если не это?
@bryc, возможно, принятое решение или другое решение отсюда. Если вам не важна производительность, вы можете использовать это
Вы также можете использовать этот трюк:
var arrayContains = function(object) {
return (serverList.filter(function(currentObject) {
if (currentObject === object) {
return currentObject
}
else {
return false;
}
}).length > 0) ? true : false
}
это кажется запутанным. «объект» - плохое название, «предмет» могло бы быть лучше. логика функции фильтра должна просто возвращать currentObject === item; и тернарный оператор не нужен ..
Решение, работающее во всех современных браузерах:
function contains(arr, obj) {
const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
return arr.some(item => JSON.stringify(item) === stringifiedObj);
}
Использование:
contains([{a: 1}, {a: 2}], {a: 1}); // true
Решение IE6 +:
function contains(arr, obj) {
var stringifiedObj = JSON.stringify(obj)
return arr.some(function (item) {
return JSON.stringify(item) === stringifiedObj;
});
}
// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
Array.prototype.some = function (tester, that /*opt*/) {
for (var i = 0, n = this.length; i < n; i++) {
if (i in this && tester.call(that, this[i], i, this)) return true;
} return false;
};
}
Использование:
contains([{a: 1}, {a: 2}], {a: 1}); // true
JSON.stringify?Array.indexOf и Array.includes (а также большинство ответов здесь) сравниваются только по ссылке, а не по значению.
[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object
Неоптимизированный однострочник ES6:
[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true
Примечание: Сравнение объектов по значению будет работать лучше, если ключи находятся в одном порядке, поэтому для безопасности вы можете сначала отсортировать ключи с помощью такого пакета: https://www.npmjs.com/package/sort-keys
Обновлена функция contains с оптимизацией производительности. Спасибо поездка за указание на это.
Этот конкретный фрагмент кода может работать в IE6 (не тестировался), но IE не поддерживал ES5 до IE9.
По соображениям производительности вам следует избегать стягивания. По крайней мере, вам следует избегать JSON.stringify "obj" в каждом цикле, потому что это дорого и замедлит ваше приложение. Поэтому вы должны захватить его перед циклом for во временной переменной.
@itinance хороший момент. Обновил функцию includes с учетом вашего предложения. Я запустил jsperf со своей функцией. Это примерно в 5 раз медленнее, чем у lodash. Хотя lodash не сравнивается по стоимости и не может найти {a: 1} в [{a: 1}]. Не знаю, делает ли это какая-нибудь библиотека. Но мне любопытно, есть ли еще эффективный и не безумно сложный способ сделать это.
Позднее примечание: это не работает, скажем, с contains([{ a: 1, b: 2 }], { b: 2, a: 1 }), потому что строковые объекты поддерживают порядок свойств.
@HereticMonkey, правда. Вот почему я добавил примечание sort-keys внизу
Или это решение:
Array.prototype.includes = function (object) {
return !!+~this.indexOf(object);
};
Хорошо, вы можете просто код оптимизируйте свой, чтобы получить результат!
Есть много способов сделать это чище и лучше, но я просто хотел получить ваш шаблон и применить к нему с помощью JSON.stringify, просто сделайте что-то вроде этого в вашем случае:
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
return true;
}
}
return false;
}
Позднее примечание: это не работает, скажем, с contains([{ a: 1, b: 2 }], { b: 2, a: 1 }), потому что строковые объекты поддерживают порядок свойств.
Использование idnexOf () - хорошее решение, но вы должны скрыть встроенную реализацию функции indexOf (), которая возвращает -1 с помощью оператора ~:
function include(arr,obj) {
return !!(~arr.indexOf(obj));
}
Array.indexOf(Object).Array.includes(Object).С ECMA 6 вы можете использовать Array.find(FunctionName), где FunctionName - пользователь
определенная функция для поиска объекта в массиве.
Надеюсь это поможет!
Я работал над проектом, в котором мне нужна была такая функциональность, как python set, которая удаляет все повторяющиеся значения и возвращает новый список, поэтому я написал, что эта функция может быть кому-то полезна.
function set(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (res.indexOf(arr[i]) === -1) {
res.push(arr[i]);
}
}
return res;
}
У него один параметр: массив номеров объектов. Каждый объект в массиве имеет два целочисленных свойства, обозначенных x и y. Функция должна возвращать количество всех таких объектов в массиве, которые удовлетворяют требованиям numbers.x == numbers.y.
var numbers = [ { x: 1, y: 1 },
{ x: 2, y: 3 },
{ x: 3, y: 3 },
{ x: 3, y: 4 },
{ x: 4, y: 5 } ];
var count = 0;
var n = numbers.length;
for (var i =0;i<n;i++)
{
if (numbers[i].x==numbers[i].y)
{count+=1;}
}
alert(count);Как бы вы сравнили значение x со значением x следующего элемента? Это не работает: for (var i = 0; i < n; i++) { if (numbers[i].x == (numbers[i] + 1).x) { count += 1; } }
Если вы работаете с ES6, вы можете использовать набор:
function arrayHas( array, element ) {
const s = new Set(array);
return s.has(element)
}
Это должно быть более производительным, чем любой другой метод.
Как он эффективнее? По крайней мере, вам нужно построить набор, который является На) (вам нужно выполнить итерацию по массиву). Простой линейный поиск (как это делает indexOf) - тоже На), но только в худшем случае. Средняя сложность случая больше похожа на п / 2, поскольку, если массив включает элемент, вы, скорее всего, остановитесь где-то посередине. Следовательно, этот метод в среднем медленнее, чем Array#includes и Array#indexOf.
Я рекомендовал использовать библиотеку подчеркивания, потому что она возвращает значение и поддерживается всеми браузерами.
var findValue = _.find(array, function(item) {
return item.id == obj.id;
});
Simple solution : ES6 Features "includes" method
let arr = [1, 2, 3, 2, 3, 2, 3, 4];
arr.includes(2) // true
arr.includes(93) // false
В дополнение к тому, что говорили другие, если у вас нет ссылки на объект, который вы хотите искать в массиве, вы можете сделать что-то вроде этого.
let array = [1, 2, 3, 4, {"key": "value"}];
array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true
array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true
Array.some возвращает true, если какой-либо элемент соответствует заданному условию, и возвращает false, если ни один из элементов не соответствует данному условию.
Позднее примечание: это не работает, скажем, с contains([{ a: 1, b: 2 }], { b: 2, a: 1 }), потому что строковые объекты поддерживают порядок свойств.
function countArray(originalArray) {
var compressed = [];
// make a copy of the input array
var copyArray = originalArray.slice(0);
// first loop goes over every element
for (var i = 0; i < originalArray.length; i++) {
var count = 0;
// loop over every element in the copy and see if it's the same
for (var w = 0; w < copyArray.length; w++) {
if (originalArray[i] == copyArray[w]) {
// increase amount of times duplicate is found
count++;
// sets item to undefined
delete copyArray[w];
}
}
if (count > 0) {
var a = new Object();
a.value = originalArray[i];
a.count = count;
compressed.push(a);
}
}
return compressed;
};
// It should go something like this:
var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
var newArray = countArray(testArray);
console.info(newArray);Использование включает встроенную функцию javascript, но не работает в Internet Explorer
var optval = [];
optval.push('A');
optval.push('B');
optval.push('C');
Мы можем искать строку A в массиве javascript как:
optval.includes('A') // =====> return true
Удивлен, что в этот вопрос все еще не добавлен последний синтаксис, добавив мои 2 цента.
Допустим, у нас есть массив объектов arrObj, и мы хотим найти в нем obj.
Array.prototype.индекс чего-либо -> (возвращает index или -1) обычно используется для поиска индекса элемента в массиве. Это также можно использовать для поиска объекта, но работает только в том случае, если вы передаете ссылку на тот же объект.
let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];
console.info(arrObj.indexOf(obj));// 0
console.info(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1
console.info([1, 3, 5, 2].indexOf(2)); //3
Array.prototype.включает в себя -> (возвращает правда или ложный)
console.info(arrObj.includes(obj)); //true
console.info(arrObj.includes({ name: 'Sumer', age: 36 })); //false
console.info([1, 3, 5, 2].includes(2)); //true
Array.prototype.найти -> (принимает обратный вызов, возвращает первый значение / объект, который возвращает истину в CB).
console.info(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }
console.info(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }
console.info([1, 3, 5, 2].find(e => e > 2)); //3
Array.prototype.findIndex -> (принимает обратный вызов, возвращает показатель первого значения / объекта, который возвращает истину в CB).
console.info(arrObj.findIndex(e => e.age > 40)); //1
console.info(arrObj.findIndex(e => e.age > 40)); //1
console.info([1, 3, 5, 2].findIndex(e => e > 2)); //1
Поскольку find и findIndex принимают обратный вызов, мы можем получить любой объект (даже если у нас нет ссылки) из массива, творчески установив истинное условие.
Простое решение для этого требования - использование find().
Если у вас есть массив объектов, как показано ниже,
var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];
Затем вы можете проверить, присутствует ли уже объект с вашим значением или нет
let data = users.find(object => object['id'] === '104');
если данные равны нулю, тогда нет администратора, иначе он вернет существующий объект, как показано ниже.
{id: "104", name: "admin"}
Затем вы можете найти индекс этого объекта в массиве и заменить объект, используя приведенный ниже код.
let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.info(users);
вы получите значение, как показано ниже
[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];
надеюсь, что это поможет кому-нибудь.
Сегодня, 2020.01.07, я провожу тесты на MacOs HighSierra 10.13.6 на Chrome v78.0.0, Safari v13.0.4 и Firefox v71.0.0 для 15 выбранных решений. Выводы
JSON, Set и, что удивительно, find (K, N, O) самые медленные во всех браузерахincludes (F) шустрый только на хромеfor (C, D) и indexOf (G, H) довольно быстры во всех браузерах на малых и больших массивах, поэтому, вероятно, они являются лучшим выбором для эффективного решенияfor (C, D, E) дают аналогичные результаты (~ 630 операций в секунду, но E в safari и firefox было 10 -20% медленнее, чем C и D)Я выполняю 2 тестовых случая: для массива с 10 элементами и массива с 1 миллионом элементов. В обоих случаях мы помещаем искомый элемент в середину массива.
let log = (name,f) => console.info(`${name}: 3-${f(arr,'s10')} 's7'-${f(arr,'s7')} 6-${f(arr,6)} 's3'-${f(arr,'s3')}`)
let arr = [1,2,3,4,5,'s6','s7','s8','s9','s10'];
//arr = new Array(1000000).fill(123); arr[500000]=7;
function A(a, val) {
var i = -1;
var n = a.length;
while (i++<n) {
if (a[i] === val) {
return true;
}
}
return false;
}
function B(a, val) {
var i = a.length;
while (i--) {
if (a[i] === val) {
return true;
}
}
return false;
}
function C(a, val) {
for (var i = 0; i < a.length; i++) {
if (a[i] === val) return true;
}
return false;
}
function D(a,val)
{
var len = a.length;
for(var i = 0 ; i < len;i++)
{
if (a[i] === val) return true;
}
return false;
}
function E(a, val){
var n = a.length-1;
var t = n/2;
for (var i = 0; i <= t; i++) {
if (a[i] === val || a[n-i] === val) return true;
}
return false;
}
function F(a,val) {
return a.includes(val);
}
function G(a,val) {
return a.indexOf(val)>=0;
}
function H(a,val) {
return !!~a.indexOf(val);
}
function I(a, val) {
return a.findIndex(x=> x==val)>=0;
}
function J(a,val) {
return a.some(x=> x===val);
}
function K(a, val) {
const s = JSON.stringify(val);
return a.some(x => JSON.stringify(x) === s);
}
function L(a,val) {
return !a.every(x=> x!==val);
}
function M(a, val) {
return !!a.find(x=> x==val);
}
function N(a,val) {
return a.filter(x=>x===val).length > 0;
}
function O(a, val) {
return new Set(a).has(val);
}
log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);This shippet only presents functions used in performance tests - it not perform tests itself!Массив маленький - 10 элементов
Вы можете проводить тесты на своей машине ЗДЕСЬ
Массив большой - 1.000.000 элементов
Вы можете проводить тесты на своей машине ЗДЕСЬ
Object.keys для получения всех имен свойств объекта и фильтрации всех значений, которые полностью или частично совпадают с указанной строкой.
function filterByValue(array, string) {
return array.filter(o =>
Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));
}
const arrayOfObject = [{
name: 'Paul',
country: 'Canada',
}, {
name: 'Lea',
country: 'Italy',
}, {
name: 'John',
country: 'Italy'
}];
console.info(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}]
console.info(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]Вы также можете фильтровать по определенному ключу, например.
Object.keys(o).some(k => o.country.toLowerCase().includes(string.toLowerCase())));
Теперь вы можете просто проверить количество массивов после фильтрации, чтобы проверить, содержит ли значение значение.
Надеюсь, это поможет.
Добавление уникального элемента в другой список
searchResults: [
{
name: 'Hello',
artist: 'Selana',
album: 'Riga',
id: 1,
},
{
name: 'Hello;s',
artist: 'Selana G',
album: 'Riga1',
id: 2,
},
{
name: 'Hello2',
artist: 'Selana',
album: 'Riga11',
id: 3,
}
],
playlistTracks: [
{
name: 'Hello',
artist: 'Mamunuus',
album: 'Riga',
id: 4,
},
{
name: 'Hello;s',
artist: 'Mamunuus G',
album: 'Riga1',
id: 2,
},
{
name: 'Hello2',
artist: 'Mamunuus New',
album: 'Riga11',
id: 3,
}
],
playlistName: "New PlayListTrack",
};
}
// Adding an unique track in the playList
addTrack = track => {
if (playlistTracks.find(savedTrack => savedTrack.id === track.id)) {
return;
}
playlistTracks.push(track);
this.setState({
playlistTracks
})
};
При чем здесь заданный вопрос?
Используйте indexOf ()
Вы можете использовать метод indexOf (), чтобы проверить, существует ли данное значение или элемент в массиве или нет. Метод indexOf () возвращает индекс элемента внутри массива, если он найден, и возвращает -1, если он не найден. Давайте посмотрим на следующий пример:
var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];
var a = "Mango";
checkArray(a, fruits);
function checkArray(a, fruits) {
// Check if a value exists in the fruits array
if (fruits.indexOf(a) !== -1) {
return document.write("true");
} else {
return document.write("false");
}
}Используйте метод include ()
ES6 представил метод includes () для очень простого выполнения этой задачи. Но этот метод возвращает только истину или ложь вместо номера индекса:
var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];
alert(fruits.includes("Banana")); // Outputs: true
alert(fruits.includes("Coconut")); // Outputs: false
alert(fruits.includes("Orange")); // Outputs: true
alert(fruits.includes("Cherry")); // Outputs: falseДля получения дополнительной информации см. здесь
Это может быть решение подробно и легко.
//plain array
var arr = ['a', 'b', 'c'];
var check = arr.includes('a');
console.info(check); //returns true
if (check)
{
// value exists in array
//write some codes
}
// array with objects
var arr = [
{x:'a', y:'b'},
{x:'p', y:'q'}
];
// if you want to check if x:'p' exists in arr
var check = arr.filter(function (elm){
if (elm.x == 'p')
{
return elm; // returns length = 1 (object exists in array)
}
});
// or y:'q' exists in arr
var check = arr.filter(function (elm){
if (elm.y == 'q')
{
return elm; // returns length = 1 (object exists in array)
}
});
// if you want to check, if the entire object {x:'p', y:'q'} exists in arr
var check = arr.filter(function (elm){
if (elm.x == 'p' && elm.y == 'q')
{
return elm; // returns length = 1 (object exists in array)
}
});
// in all cases
console.info(check.length); // returns 1
if (check.length > 0)
{
// returns true
// object exists in array
//write some codes
}
используйте Array.prototype.includes, например:
const fruits = ['coconut', 'banana', 'apple']
const doesFruitsHaveCoconut = fruits.includes('coconut')// true
console.info(doesFruitsHaveCoconut)возможно, прочтите эту документацию из MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
Вы можете использовать функцию findIndex, чтобы проверить, имеет ли массив определенное значение.
arrObj.findIndex(obj => obj === comparedValue) !== -1;
Возвращает true, если arrObj содержит compareValue, в противном случае - false.
только что протестировано: ваш способ на самом деле самый быстрый для всех браузеров: jsperf.com/find-element-in-obj-vs-array/2 (кроме предварительного сохранения a.length в переменной) при использовании indexOf (как в $ .inArray) намного медленнее