Best way to find if an item is in a JavaScript array? [duplicate]
This question already has an answer here:
How do I check if an array includes an object in JavaScript?
46 answers
What is the best way to find if an object is in an array? As of ECMAScript 2016 you can use If you want to support IE or other older browsers: EDIT: Mozilla’s (ECMA-262) version: Daniel James‘s version: roosteronacid‘s version: If you are using jQuery: For more information: http://api.jquery.com/jQuery.inArray/ First, implement It’s changed to store the length so that it doesn’t need to look it up every iteration. But the difference isn’t huge. A less general purpose function might be faster: I prefer using the standard function and leaving this sort of micro-optimization for when it’s really needed. But if you’re keen on micro-optimization I adapted the benchmarks that roosterononacid linked to in the comments, to benchmark searching in arrays. They’re pretty crude though, a full investigation would test arrays with different types, different lengths and finding objects that occur in different places. If the array is unsorted, there isn’t really a better way (aside from using the above-mentioned indexOf, which I think amounts to the same thing). If the array is sorted, you can do a binary search, which works like this: Binary search runs in time proportional to the logarithm of the length of the array, so it can be much faster than looking at each individual element. [ ].has(obj) assuming !!! do not make the use of 2nd arg (flag) forces comparation by value instead of reference comparing raw objects It depends on your purpose. If you program for the Web, avoid
This is the best way I know:
function include(arr, obj) {
for(var i=0; iSolutions/Answers:
Solution 1:
includes()
arr.includes(obj);
function include(arr,obj) {
return (arr.indexOf(obj) != -1);
}
This will not work on IE6, 7 or 8 though. The best workaround is to define it yourself if it’s not present:
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(searchElement /*, fromIndex */)
{
"use strict";
if (this === void 0 || 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 > 0)
{
n = Number(arguments[1]);
if (n !== n)
n = 0;
else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
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;
};
}
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i] === obj)
return i;
}
return -1;
};
}
Array.prototype.hasObject = (
!Array.indexOf ? function (o)
{
var l = this.length + 1;
while (l -= 1)
{
if (this[l - 1] === o)
{
return true;
}
}
return false;
} : function (o)
{
return (this.indexOf(o) !== -1);
}
);
Solution 2:
$.inArray(5 + 5, [ "8", "9", "10", 10 + "" ]);
Solution 3:
indexOf
in JavaScript for browsers that don’t already have it. For example, see Erik Arvidsson’s array extras (also, the associated blog post). And then you can use indexOf
without worrying about browser support. Here’s a slightly optimised version of his indexOf
implementation:if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length + fromIndex);
}
for (var i = fromIndex, j = this.length; i < j; i++) {
if (this[i] === obj)
return i;
}
return -1;
};
}
var include = Array.prototype.indexOf ?
function(arr, obj) { return arr.indexOf(obj) !== -1; } :
function(arr, obj) {
for(var i = -1, j = arr.length; ++i < j;)
if(arr[i] === obj) return true;
return false;
};
Solution 4:
Solution 5:
.indexOf()
is implemented Object.defineProperty( Array.prototype,'has',
{
value:function(o, flag){
if (flag === undefined) {
return this.indexOf(o) !== -1;
} else { // only for raw js object
for(var v in this) {
if( JSON.stringify(this[v]) === JSON.stringify(o)) return true;
}
return false;
},
// writable:false,
// enumerable:false
})
Array.prototype.has=function(){...
because you’ll add an enumerable element in every array and js is broken.//use like
[22 ,'a', {prop:'x'}].has(12) // false
["a","b"].has("a") // true
[1,{a:1}].has({a:1},1) // true
[1,{a:1}].has({a:1}) // false
[o1].has(o2,true) // true if every level value is same
Solution 6:
indexOf
, it isn’t supported by Internet Explorer 6 (lot of them still used!), or do conditional use:if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target);
else result = customSlowerSearch(yourArray, target);
indexOf
is probably coded in native code, so it is faster than anything you can do in JavaScript (except binary search/dichotomy if the array is appropriate).
Note: it is a question of taste, but I would do a return false;
at the end of your routine, to return a true Boolean…