Определите, содержит ли массив значение

Мне нужно определить, существует ли значение в массиве.

Я использую следующую функцию:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return true;
        }
    }
    return false;
}

Вышеуказанная функция всегда возвращает false.

Значения массива и вызов функции следующие:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));

Ответы

Ответ 1

var contains = function(needle) {
    // Per spec, the way to identify NaN is that it is not equal to itself
    var findNaN = needle !== needle;
    var indexOf;

    if(!findNaN && typeof Array.prototype.indexOf === 'function') {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function(needle) {
            var i = -1, index = -1;

            for(i = 0; i < this.length; i++) {
                var item = this[i];

                if((findNaN && item !== item) || item === needle) {
                    index = i;
                    break;
                }
            }

            return index;
        };
    }

    return indexOf.call(this, needle) > -1;
};

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

var myArray = [0,1,2],
    needle = 1,
    index = contains.call(myArray, needle); // true

Проверка/использование CodePen

Ответ 3

Это, как правило, метод indexOf(). Вы сказали бы:

return arrValues.indexOf('Sam') > -1

Ответ 4

Array.prototype.includes()

В ES2016 есть Array.prototype.includes().

Метод includes() определяет, содержит ли массив некоторый элемент, возвращая true или false, если это необходимо.

Пример

["Sam", "Great", "Sample", "High"].includes("Sam"); // true

Поддержка

Согласно kangax и MDN, поддерживаются следующие платформы:

  • Chrome 47
  • Край 14
  • Firefox 43
  • Opera 34
  • Safari 9
  • Node 6

Поддержка может быть расширена с помощью Babel (используя babel-polyfill) или core-js. MDN также предоставляет polyfill:

if (![].includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

Ответ 5

Почти всегда безопаснее использовать библиотеку, такую как lodash, просто из-за всех проблем с совместимостью и эффективностью кросс-браузера.

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

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

Если вас беспокоит объем, добавляемый в ваше приложение, включая всю библиотеку, знайте, что вы можете включать функциональность отдельно:

var includes = require('lodash/collections/includes');

УВЕДОМЛЕНИЕ. В более старых версиях lodash это _.contains() а не _.includes().

Ответ 6

tl; dr

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

Пример

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

function log(msg){
  $('#out').append('<div>' + msg + '</div>');  
}

var arr = [1, "2", NaN, true];
arr.includes = includes;

log('var arr = [1, "2", NaN, true];');
log('<br/>');
log('arr.includes(1): ' + arr.includes(1));
log('arr.includes(2): ' + arr.includes(2));
log('arr.includes("2"): ' + arr.includes("2"));
log('arr.includes(NaN): ' + arr.includes(NaN));
log('arr.includes(true): ' + arr.includes(true));
log('arr.includes(false): ' + arr.includes(false));
#out{
  font-family:monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=out></div>

Ответ 7

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

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

Ответ 8

Мой маленький вклад:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

//usage
if(isInArray(my_array, "my_value"))
{
    //...
}

Ответ 9

Учитывая реализацию indexOf для IE (как описано без ведома):

Array.prototype.contains = function(obj) {
    return this.indexOf(obj) > -1;
};

Ответ 10

Если у вас есть доступ к ECMA 5, вы можете использовать метод some.

MDN Некоторая ссылка метода

arrValues = ["Sam","Great", "Sample", "High"];

function namePresent(name){
  return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"

arrValues.some(namePresent, 'Sam');
=> true;

Если у вас есть доступ к ECMA 6, вы можете использовать метод включает.

MDN ВКЛЮЧАЕТ ссылку на метод

arrValues = ["Sam","Great", "Sample", "High"];

arrValues.includes('Sam');
=> true;

Ответ 11

Вы можете использовать _. метод indexOf или если вы не хотите включать всю библиотеку Underscore.js в свое приложение, вы можете посмотрите как они это сделали и извлеките необходимый код.

    _.indexOf = function(array, item, isSorted) {
    if (array == null) return -1;
    var i = 0, l = array.length;
    if (isSorted) {
      if (typeof isSorted == 'number') {
        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
      } else {
        i = _.sortedIndex(array, item);
        return array[i] === item ? i : -1;
      }
    }
    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    for (; i < l; i++) if (array[i] === item) return i;
    return -1;
  };

Ответ 12

Другой вариант - использовать Array.some (если доступно) следующим образом:

Array.prototype.contains = function(obj) {
  return this.some( function(e){ return e === obj } );
}

Анонимная функция, переданная в Array.some, вернет true тогда и только тогда, когда в массиве есть элемент, идентичный obj. Отсутствие такого элемента, функция не вернет true для любого из элементов массива, поэтому Array.some также вернет false.

Ответ 13

Ничего себе, на этот вопрос есть много отличных ответов.

Я не видел того, который принимает подход reduce, поэтому я добавлю его в:

var searchForValue = 'pig';

var valueIsInArray = ['horse', 'cat', 'dog'].reduce(function(previous, current){
    return previous || searchForValue === current ? true : false;
}, false);

console.log('The value "' + searchForValue + '" is in the array: ' + valueIsInArray);

Здесь скрипка в действии.

Ответ 14

Ответ предоставлен не для меня, но он дал мне идею:

Array.prototype.contains = function(obj)
    {
        return (this.join(',')).indexOf(obj) > -1;
    }

Это не идеально, потому что элементы, которые являются одинаковыми вне группировок, могут привести к совпадению. Например, мой пример

var c=[];
var d=[];
function a()
{
    var e = '1';
    var f = '2';
    c[0] = ['1','1'];
    c[1] = ['2','2'];
    c[2] = ['3','3'];
    d[0] = [document.getElementById('g').value,document.getElementById('h').value];

    document.getElementById('i').value = c.join(',');
    document.getElementById('j').value = d.join(',');
    document.getElementById('b').value = c.contains(d);
}

Когда я вызываю эту функцию с полями "g" и "h", содержащими 1 и 2 соответственно, он все равно находит это, потому что результирующая строка из объединения: 1,1,2,2,3,3

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

Ответ 15

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

Ссылка: Array.prototype.map()

Этот метод может хорошо работать как для простых массивов, так и для массивов объектов, где вам нужно увидеть, существует ли ключ/значение в массиве объектов.

function inArray(myArray,myValue){
    var inArray = false;
    myArray.map(function(key){
        if (key === myValue){
            inArray=true;
        }
    });
    return inArray;
};

var anArray = [2,4,6,8]
console.log(inArray(anArray, 8)); // returns true
console.log(inArray(anArray, 1)); // returns false

function inArrayOfObjects(myArray,myValue,objElement){
    var inArray = false;
    myArray.map(function(arrayObj){
        if (arrayObj[objElement] === myValue) {
            inArray=true;
        }
    });
    return inArray;
};

var objArray = [{id:4,value:'foo'},{id:5,value:'bar'}]
console.log(inArrayOfObjects(objArray, 4, 'id')); // returns true
console.log(inArrayOfObjects(objArray, 'bar', 'value')); // returns true
console.log(inArrayOfObjects(objArray, 1, 'id')); // returns false

Ответ 16

function setFound(){   
 var l = arr.length, textBox1 = document.getElementById("text1");
    for(var i=0; i<l;i++)
    {
     if(arr[i]==searchele){
      textBox1 .value = "Found";
      return;
     }
    }
    textBox1 .value = "Not Found";
return;
}

Эта программа проверяет, найден ли данный элемент или нет. Я бы text1 представляет собой идентификатор текстового поля, а поисковый запрос представляет элемент, который должен быть поиск (получил пользователь fron); если вам нужен индекс, используйте значение i

Ответ 17

Простейшим решением для функции contains будет функция, которая выглядит так:

var contains = function (haystack, needle) {
    return !!~haystack.indexOf(needle);
}

В идеале вы бы не сделали это автономной функцией, а частью вспомогательной библиотеки:

var helper = {};

helper.array = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);
    }, 
    ...
};

Теперь, если вы оказались одним из тех неудачливых людей, которые все еще нуждаются в поддержке IE < 9 и, следовательно, не могут полагаться на indexOf, вы можете использовать этот polyfill, который я получил из MDN:

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {
    var k;
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }
    var o = Object(this);
    var len = o.length >>> 0;
    if (len === 0) {
      return -1;
    }
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }
    if (n >= len) {
      return -1;
    }
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    while (k < len) {
      if (k in o && o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}

Ответ 18

Я очень рекомендую это -

if(/Element/g.test(Array)){---}

Ответ 19

Я предпочитаю простоту:

var days = [1, 2, 3, 4, 5];
if ( 2 in days ) {console.log('weekday');}