Best way to find if an item is in a JavaScript array?
找到对象是否在数组中的最好方法是什么?
这是我知道的最好的方法:
1 2 3 4 5 6 7 8 | function include(arr, obj) { for(var i=0; i<arr.length; i++) { if (arr[i] == obj) return true; } } include([1,2,3,4], 3); // true include([1,2,3,4], 6); // undefined |
从ecmascript 2016起,您可以使用
1 | arr.includes(obj); |
如果要支持IE或其他较旧的浏览器:
1 2 3 | function include(arr,obj) { return (arr.indexOf(obj) != -1); } |
编辑:但这在IE6、7或8上不起作用。最好的解决方法是自己定义它,如果它不存在:
Mozilla(ECMA-262)版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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; }; } |
丹尼尔·詹姆斯的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; }; } |
Roosteronacid的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); } ); |
如果使用jQuery:
1 | $.inArray(5 + 5, ["8","9","10", 10 +"" ]); |
有关更多信息:HTTP://API.jQueR.COM/jQueR.InAARYA/
首先,在还没有的浏览器中用JavaScript实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; }; } |
它被更改为存储长度,这样就不需要每次迭代都查找它了。但差别不大。不太通用的功能可能更快:
1 2 3 4 5 6 7 | 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; }; |
我更喜欢使用标准函数,并且在需要的时候保留这种微优化。但是,如果你热衷于微优化,我将基准中的ROOSTONNONE链接到评论中,以便在数组中进行基准搜索。它们是相当粗糙的,但是,一个完整的调查将测试不同类型,不同长度的阵列,并发现在不同的地方发生的物体。
如果数组没有排序,那么就没有更好的方法了(除了使用上面提到的indexof,我认为这是一回事)。如果对数组进行排序,则可以执行二进制搜索,其工作方式如下:
二进制搜索的运行时间与数组长度的对数成比例,因此它可能比查看每个元素快得多。
[](OBJ)
假设执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 }) |
!!!!不要使用
1 2 3 4 5 6 | //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 |
使用第二个arg(flag)强制按值而不是参照进行比较
比较原始对象
1 | [o1].has(o2,true) // true if every level value is same |
这取决于你的目的。如果您为Web编程,请避免使用
1 2 | if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target); else result = customSlowerSearch(yourArray, target); |
以下是一些元知识-如果您想知道如何使用数组,请查看文档-这是Mozilla的数组页面
https://developer.mozilla.org/en-us/docs/javascript/reference/global_对象/array
在这里,您将看到在javascript 1.6中添加的indexof的引用。
在JavaScript中检查对象是否为数组的健壮方法详述如下:
下面是xa.js框架中的两个函数,我将它们附加到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var utils = {}; /** * utils.isArray * * Best guess if object is an array. */ utils.isArray = function(obj) { // do an instanceof check first if (obj instanceof Array) { return true; } // then check for obvious falses if (typeof obj !== 'object') { return false; } if (utils.type(obj) === 'array') { return true; } return false; }; /** * utils.type * * Attempt to ascertain actual object type. */ utils.type = function(obj) { if (obj === null || typeof obj === 'undefined') { return String (obj); } return Object.prototype.toString.call(obj) .replace(/\[object ([a-zA-Z]+)\]/, '$1').toLowerCase(); }; |
如果要检查对象是否在数组中,我还将包括以下代码:
1 2 3 4 5 6 7 8 9 10 11 | /** * Adding hasOwnProperty method if needed. */ if (typeof Object.prototype.hasOwnProperty !== 'function') { Object.prototype.hasOwnProperty = function (prop) { var type = utils.type(this); type = type.charAt(0).toUpperCase() + type.substr(1); return this[prop] !== undefined && this[prop] !== window[type].prototype[prop]; }; } |
最后,在数组函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function in_array (needle, haystack, strict) { var key; if (strict) { for (key in haystack) { if (!haystack.hasOwnProperty[key]) continue; if (haystack[key] === needle) { return true; } } } else { for (key in haystack) { if (!haystack.hasOwnProperty[key]) continue; if (haystack[key] == needle) { return true; } } } return false; } |