Sample query:
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?
How to check if an array includes a value in JavaScript? Answer #1:
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:
- jQuery:
$.inArray(value, array, [fromIndex])
- Underscore.js:
_.contains(array, value)
(also aliased as_.include
and_.includes
) - Dojo Toolkit:
dojo.indexOf(array, value, [fromIndex, findLast])
- Prototype:
array.indexOf(value)
- MooTools:
array.indexOf(value)
- MochiKit:
findValue(array, value)
- MS Ajax:
array.indexOf(value)
- Ext:
Ext.Array.contains(array, value)
- Lodash:
_.includes(array, value, [from])
(is_.contains
prior 4.0.0) - Ramda:
R.includes(value, array)
Notice that some frameworks implement this as a function, while others add the function to the array prototype.
Check if an array includes a value- Answer #2:
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
Answer #3:
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.
Answer #4:
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
Currently it’s still a draft but can be polyfilled to make it work on all browsers.
Answer #5:
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
}
Now, Array.prototype.some()
is fully supported: caniuse.com support table.
Answer #6:
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
How to check if an array includes a value in JavaScript? Answer #7:
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;
};
}
Answer #8:
A hopefully faster bidirectional indexOf
/ lastIndexOf
alternative
2015
While the new method includes is very nice, the support is basically zero for now.
It’s long time that I was thinking of way to replace the slow indexOf/lastIndexOf functions.
A performant way has already been found, looking at the top answers. From those, I chose the contains
function posted by @Damir Zekic which should be the fastest one. But it also states that the benchmarks are from 2008 and so are outdated.
I also prefer while
over for
, but for not a specific reason I ended writing the function with a for loop. It could be also done with a while --
.
I was curious if the iteration was much slower if I check both sides of the array while doing it. Apparently no, and so this function is around two times faster than the top voted ones. Obviously it’s also faster than the native one. This in a real world environment, where you never know if the value you are searching is at the beginning or at the end of the array.
When you know you just pushed an array with a value, using lastIndexOf remains probably the best solution, but if you have to travel through big arrays and the result could be everywhere, this could be a solid solution to make things faster.
Bidirectional 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');
Performance test
As test, I created an array with 100k entries.
Three queries: at the beginning, in the middle & at the end of the array.
I hope you also find this interesting and test the performance.
Note: As you can see I slightly modified the contains
function to reflect the indexOf & lastIndexOf output (so basically true
with the index
and false
with -1
). That shouldn’t harm it.
The array prototype variant
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');
The function can also be easily modified to return true or false or even the object, string or whatever it is.
And here is the while
variant:
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');
How is this possible?
I think that the simple calculation to get the reflected index in an array is so simple that it’s two times faster than doing an actual loop iteration.
Here is a complex example doing three checks per iteration, but this is only possible with a longer calculation which causes the slowdown of the code.
Hope you learned something from this post.
Follow Programming Articles for more!