How Do I Check If an Array Includes a Value in Javascript?

How Do I Check If an Array Includes a Value in Javascript?

What is the most concise and efficient way to find out if a JavaScript array contains a value?

This is the only way I know to do it:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

Is there a better and more concise way to accomplish this?

10

57 Answers

Modern browsers have Array#includes, which does exactly that and is widely supported by everyone except IE:

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

You can also use Array#indexOf, which is less direct, but doesn't require polyfills for outdated browsers.

console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //true

Many frameworks also offer similar methods:

Notice that some frameworks implement this as a function, while others add the function to the array prototype.

8

Update from 2019: This answer is from 2008 (11 years old!) and is not relevant for modern JS usage. The promised performance improvement was based on a benchmark done in browsers of that time. It might not be relevant to modern JS execution contexts. If you need an easy solution, look for other answers. If you need the best performance, benchmark for yourself in the relevant execution environments.

As others have said, the iteration through the array is probably the best way, but it has been proven that a decreasing while loop is the fastest way to iterate in JavaScript. So you may want to rewrite your code as follows:

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

Of course, you may as well extend Array prototype:

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

And now you can simply use the following:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
2

indexOf maybe, but it's a "JavaScript extension to the ECMA-262 standard; as such it may not be present in other implementations of the standard."

Example:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS Microsoft does not offer some kind of alternative to this, but you can add similar functionality to arrays in Internet Explorer (and other browsers that don't support indexOf) if you want to, as a quick Google search reveals (for example, this one).

0

The top answers assume primitive types but if you want to find out if an array contains an object with some trait, Array.prototype.some() is an elegant solution:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

The nice thing about it is that the iteration is aborted once the element is found so unnecessary iteration cycles are spared.

Also, it fits nicely in an if statement since it returns a boolean:

if (items.some(item => item.a === '3')) {
  // do something
}

* As jamess pointed out in the comment, at the time of this answer, September 2018, Array.prototype.some() is fully supported: caniuse.com support table

0

ECMAScript 7 introduces Array.prototype.includes.

It can be used like this:

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

It also accepts an optional second argument fromIndex:

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

Unlike indexOf, which uses Strict Equality Comparison, includes compares using SameValueZero equality algorithm. That means that you can detect if an array includes a NaN:

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

Also unlike indexOf, includes does not skip missing indices:

new Array(5).includes(undefined); // true

It can be polyfilled to make it work on all browsers.

0

Let's say you've defined an array like so:

const array = [1, 2, 3, 4]

Below are three ways of checking whether there is a 3 in there. All of them return either true or false.

Native Array method (since ES2016) (compatibility table)

array.includes(3) // true

As custom Array method (pre ES2016)

// 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

Simple function

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true
1

Here's a JavaScript 1.6 compatible implementation of Array.indexOf:

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;
        };
}
4

Use:

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

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

Extending the JavaScript Array object is a really bad idea because you introduce new properties (your custom methods) into for-in loops which can break existing scripts. A few years ago the authors of the Prototype library had to re-engineer their library implementation to remove just this kind of thing.

If you don't need to worry about compatibility with other JavaScript running on your page, go for it, otherwise, I'd recommend the more awkward, but safer free-standing function solution.

1

Performance

Today 2020.01.07 I perform tests on MacOs HighSierra 10.13.6 on Chrome v78.0.0, Safari v13.0.4 and Firefox v71.0.0 for 15 chosen solutions. Conclusions

  • solutions based on JSON, Set and surprisingly find (K,N,O) are slowest on all browsers
  • the es6 includes (F) is fast only on chrome
  • the solutions based on for (C,D) and indexOf (G,H) are quite-fast on all browsers on small and big arrays so probably they are best choice for efficient solution
  • the solutions where index decrease during loop, (B) is slower probably because the way of CPU cache works.
  • I also run test for big array when searched element was on position 66% of array length, and solutions based on for (C,D,E) gives similar results (~630 ops/sec - but the E on safari and firefox was 10-20% slower than C and D)
Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.