Проверьте, присутствует ли элемент в массиве

Функция, которую я использую сейчас, чтобы проверить это, следующая:

function inArray(needle,haystack)
{
    var count=haystack.length;
    for(var i=0;i<count;i++)
    {
        if(haystack[i]===needle){return true;}
    }
    return false;
}

Это работает. Я ищу, есть ли лучший способ сделать это.

Ответ 1

ECMAScript 2016 включает метод includes() для массивов, который конкретно решает проблему, и поэтому теперь является предпочтительным методом.

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(1, 2);  // false (second parameter is the index position in this array at which to begin searching)

По состоянию на июль 2018 года этот был реализован почти во всех основных браузерах, если вам нужна поддержка IE, доступен полифилл.

Изменение: Обратите внимание, что это возвращает false, если элемент в массиве является объектом. Это потому, что похожие объекты - это два разных объекта в JavaScript.

Ответ 2

Код:

function isInArray(value, array) {
  return array.indexOf(value) > -1;
}

Исполнение:

isInArray(1, [1,2,3]); // true

Обновление (2017):

В современных браузерах, которые следуют стандарту ECMAScript 2016 (ES7), вы можете использовать функцию Array.prototype.includes, которая упрощает проверку наличия элемента в массиве:

const array = [1, 2, 3];
const value = 1;
const isInArray = array.includes(value);
console.log(isInArray); // true

Ответ 3

Просто используйте indexOf:

haystack.indexOf(needle) >= 0

Если вы хотите поддерживать старые поисковые системы Интернета (< IE9), вам придется включить ваш текущий код в качестве обходного пути, хотя.

Если ваш список не отсортирован, вам нужно сравнить каждое значение с иглой. Таким образом, как ваше решение, так и indexOf должны будут выполнять сравнения n/2 в среднем. Однако, поскольку indexOf является встроенным методом, он может использовать дополнительные оптимизации и на практике будет немного быстрее. Обратите внимание, что, если ваше приложение не ищет в списках очень часто (скажем, 1000 раз в секунду), или списки огромны (скажем, 100 тыс. Записей), разница в скорости не будет иметь значения.

Ответ 4

Я сравнивал это несколько раз в Google Chrome 52, но не стесняюсь копировать его в любую другую консоль браузера.


~ 1500 мс, включает (~ 2700 мс, когда я использовал polyfill)

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.includes("test") === true){ result++; }
}
console.log(new Date().getTime() - start);

~ 1050 мс, indexOf

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(array.indexOf("test") > -1){ result++; }
}
console.log(new Date().getTime() - start);

~ 650 мс, пользовательская функция

function inArray(target, array)
{

/* Caching array.length doesn't increase the performance of the for loop on V8 (and probably on most of other major engines) */

  for(var i = 0; i < array.length; i++) 
  {
    if(array[i] === target)
    {
      return true;
    }
  }

  return false; 
}

var array = [0,1,2,3,4,5,6,7,8,9]; 
var result = 0;

var start = new Date().getTime();
for(var i = 0; i < 10000000; i++)
{
  if(inArray("test", array) === true){ result++; }
}
console.log(new Date().getTime() - start);

Ответ 5

Код отдельной строки.. вернет true или false

!!(arr.indexOf("val")+1)

Ответ 6

Вы можете использовать indexOf но не очень хорошо работает в последней версии Internet Explorer. Код:

function isInArray(value, array) {
  return array.indexOf(value) > -1;
}

Исполнение:

isInArray(1, [1,2,3]); // true

Я предлагаю вам использовать следующий код:

function inArray(needle, haystack) {
 var length = haystack.length;
 for (var i = 0; i < length; i++) {
 if (haystack[i] == needle)
  return true;
 }
 return false;
}

Ответ 7

Вы можете использовать функцию _contains из библиотеки underscore.js для достижения этой цели:

if (_.contains(haystack, needle)) {
  console.log("Needle found.");
};

Ответ 8

С ECMAScript6 можно использовать Set:

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false

Ответ 9

В зависимости от размера иглы, которую вы ищете Array.filter, может быть полезно. Вот пример:

let filtered, arr = ['Haystack', 'Needle'];
filtered = arr.filter((elem) => {
  return elem.toLowerCase() === 'needle';
});
// filtered => ['needle']

Ответ 10

В lodash вы можете использовать _. includes (который также содержит псевдонимы _.contains)

Вы можете выполнить поиск по всему массиву:

_.includes([1, 2, 3], 1); // true

Вы можете искать массив из начального индекса:

_.includes([1, 2, 3], 1, 1);  // false (begins search at index 1)

Поиск строки:

_.includes('pebbles', 'eb');  // true (string contains eb)

Также работает для проверки простых массивов объектов:

_.includes({ 'user': 'fred', 'age': 40 }, 'fred');    // true
_.includes({ 'user': 'fred', 'age': false }, false);  // true

Одна вещь, которую следует отметить в последнем случае, - это работать с примитивами, такими как строки, числа и логические объекты, но не может выполнять поиск по массивам или объектам.

_.includes({ 'user': 'fred', 'age': {} }, {});   // false
_.includes({ 'user': [1,2,3], 'age': {} }, 3);   // false