find一个项目是否在JavaScript数组中的最佳方法?

什么是最好的方式来find一个对象是否在一个数组?

这是我知道的最好的方法:

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 
 function include(arr,obj) { return (arr.indexOf(obj) != -1); } 

编辑:这将无法在IE6,7或8上工作。 最好的解决方法是自己定义它,如果它不存在:

  1. Mozilla的 (ECMA-262)版本:

      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; }; } 
  2. 丹尼尔·詹姆斯的版本:

     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; }; } 
  3. roosteronacid的版本:

     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:

 $.inArray(5 + 5, [ "8", "9", "10", 10 + "" ]); 

欲了解更多信息: http : //api.jquery.com/jQuery.inArray/

首先,对于尚未拥有它的浏览器,在JavaScript中实现indexOf 。 例如,请参阅Erik Arvidsson的数组extras (也是关联的博客文章 )。 然后你可以使用indexOf而不用担心浏览器的支持。 这是他的indexOf实现的一个稍微优化的版本:

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

它改变了存储的长度,以便它不需要每次迭代查找它。 但差别并不大。 一个不太常用的function可能会更快:

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

我更喜欢使用标准函数,并在需要时留下这种微型优化。 但是,如果你热衷于微型优化,我将在评论中关联的基准进行了调整,以便在数组中进行基准search 。 他们是非常粗糙的,一个完整的调查将testing不同types,不同长度的数组,并find不同地方发生的对象。

如果这个数组是未sorting的,那么除了使用上面提到的indexOf(我认为它们是相同的)之外,还没有更好的方法。 如果数组已sorting,则可以执行二进制search,其工作方式如下所示:

  1. select数组的中间元素。
  2. 你所寻找的元素是否大于你select的元素? 如果是这样,你已经消除了数组的下半部分。 如果不是的话,你已经取消了上半场。
  3. 选取数组剩余部分的中间元素,然后继续执行第2步,排除剩余数组的一半。 最终你会发现你的元素,或没有数组留下来看。

二进制search的运行时间与数组长度的对数成正比,所以它比查看每个单独的元素要快得多。

假设.indexOf()被实现

 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(){...因为你将在每个数组中添加一个可枚举的元素,并且js被破坏。

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

使用第二个参数(标志)强制值的比较,而不是参考

以下是您的一些元知识 – 如果您想知道如何使用数组,请查看文档 – 这里是Mozilla的Array页面

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array

在这里你会看到对indexOf的引用,在Javascript 1.6中添加

这取决于你的目的。 如果您为Web编程,请避免使用indexOf ,Internet Explorer 6不支持它们(它们中的很多仍在使用!),或者做有条件的使用:

 if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target); else result = customSlowerSearch(yourArray, target); 

indexOf可能是用本地代码编写的,所以它比在JavaScript中可以做的任何事都快(除非二进制search/二分法,如果数组是合适的)。 注:这是一个味道的问题,但我会做一个return false; 在你的例程结束,返回一个真正的布尔…

在这里详细介绍一种可靠的方法来检查一个对象是否是一个JavaScript中的数组:

下面是我附加到utils = {} '容器'的xa.js框架中的两个函数。 这些应该会帮助你正确地检测数组。

 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(); }; 

如果你然后想检查一个对象是否在一个数组中,我也会包含这个代码:

 /** * 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]; }; } 

最后这个in_array函数:

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