如何确定对象是否在数组中

我需要确定一个对象是否已经存在于JavaScript中的数组中。

例如(dummycode):

var carBrands = []; var car1 = {name:'ford'}; var car2 = {name:'lexus'}; var car3 = {name:'maserati'}; var car4 = {name:'ford'}; carBrands.push(car1); carBrands.push(car2); carBrands.push(car3); carBrands.push(car4); 

现在“carBrands”数组包含所有实例。 我现在正在寻找一个快速的解决scheme来检查car1,car2,car3或car4的实例是否已经在carBrands数组中。

例如:

 var contains = carBrands.Contains(car1); //<--- returns bool. 

car1和car4包含相同的数据,但是不同的实例应该被testing为不相等。

我有添加像哈希到创build对象? 或者是有一个更快的方式来做到这一点在Javascript中。

我在这里寻找最快的解决scheme,如果脏,所以它必须;)在我的应用程序,它必须处理大约10000个实例。

没有jquery

使用这样的东西:

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

在这种情况下, containsObject(car4, carBrands)是真的。 删除carBrands.push(car4); 调用,它将返回false而不是。 如果稍后扩展到使用对象来存储这些其他汽车对象而不是使用数组,则可以使用类似下面的代码:

 function containsObject(obj, list) { var x; for (x in list) { if (list.hasOwnProperty(x) && list[x] === obj) { return true; } } return false; } 

这种方法也适用于数组,但在arrays上使用时,会比第一个选项慢一点。

为什么不使用javascript数组的indexOf方法?

看看这个: MDN indexOf Arrays

简单地做:

 carBrands.indexOf(car1); 

它将返回car1的索引(在数组中的位置)。 如果在数组中找不到car1,它将返回-1。

http://jsfiddle.net/Fraximus/r154cd9o

编辑:请注意,在问题中,要求是检查数组中引用同一个对象,而不是一个新的对象 。 即使新对象在内容上与数组中的对象相同,它仍然是一个不同的对象。 正如在注释中提到的, 对象在JS中通过引用传递,同一个对象可以在多个结构中多次存在。
如果你想创build一个新的对象,并检查数组是否包含与你的新对象相同的对象,这个答案将不起作用(朱利安的小提琴下面),如果你想检查数组中的同一个对象的存在,那么这个答案将工作。 看看这里和评论中的小提琴。

你可以使用jQuery的grep方法:

 $.grep(carBrands, function(obj) { return obj.name == "ford"; }); 

但是,因为你没有指定jQuery,你可以做一个函数的派生。 从源代码:

 function grepArray( elems, callback, inv ) { var ret = []; // Go through the array, only saving the items // that pass the validator function for ( var i = 0, length = elems.length; i < length; i++ ) { if ( !inv !== !callback( elems[ i ], i ) ) { ret.push( elems[ i ] ); } } return ret; } grepArray(carBrands, function(obj) { return obj.name == "ford"; }); 

您可以使用相等运算符: == 。 对象通过默认的引用来检查,所以你甚至不需要使用===运算符。

试试这个,只要确保你在car1的地方使用了正确的variables引用:

 var i, car, l = cars.length; for (i = 0; i < l; i++) { if ((car = cars[i]) == car1) { break; } else car = null; } 

编辑添加:

数组扩展被提到,所以这是它的代码:

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

请注意,我正在caching长度值,因为数组的length属性实际上是一个访问器,它比内部variables稍慢。

我使用underscore JavaScript库来调整这个问题。

 function containsObject(obj, list) { var res = _.find(list, function(val){ return _.isEqual(obj, val)}); return (_.isObject(res))? true:false; } 

请参阅上面例子中使用的下划线函数的underscore.js文档。

注意:我的解决scheme不是纯JavaScript,因为它使用其他js库。 我只是添加了这个信息的目的。

我会在数组上使用属性/值的generics迭代器。 不需要jQuery。

 arr = [{prop1: 'val1', prop2: 'val2'}, {prop1: 'val3', prop2: 'val4'}]; objectPropInArray(arr, 'prop1', 'val3'); // <-- returns true function objectPropInArray(list, prop, val) { if (list.length > 0 ) { for (i in list) { if (list[i][prop] === val) { return true; } } } return false; } 

尝试Array.prototype.some()

MDN Array.prototype.some

“`javascipt的

 function isBiggerThan10(element, index, array) { return element > 10; } [2, 5, 8, 1, 4].some(isBiggerThan10); // false [12, 5, 8, 1, 4].some(isBiggerThan10); // true 

“`

最近刚刚被FP错误所困扰,读到了很多关于function范式如何整合Javascript的精彩报道

为了完整起见,我复制了代码,并提出了两种可以在function上完成的方法。

  var carBrands = []; var car1 = {name:'ford'}; var car2 = {name:'lexus'}; var car3 = {name:'maserati'}; var car4 = {name:'ford'}; var car5 = {name:'toyota'}; carBrands.push(car1); carBrands.push(car2); carBrands.push(car3); carBrands.push(car4); // ES6 approach which uses the includes method (Chrome47+, Firefox43+) carBrands.includes(car1) // -> true carBrands.includes(car5) // -> false 

如果您需要支持旧浏览器使用polyfill,看来IE9 +和Edge不支持它。 位于MSDN页面的填充部分

或者,我想提出一个更新的答案cdhowie

 // ES2015 syntax function containsObject(obj, list) { return list.some(function(elem) { return elem === obj }) } // or ES6+ syntax with cool fat arrows function containsObject(obj, list) { return list.some(elem => elem === obj) } 

您可以尝试基于属性对数组进行sorting,如下所示:

 carBrands = carBrands.sort(function(x,y){ return (x == y) ? 0 : (x > y) ? 1 : -1; }); 

然后你可以使用一个迭代例程来检查是否

 carBrands[Math.floor(carBrands.length/2)] // change carBrands.length to a var that keeps // getting divided by 2 until result is the target // or no valid target exists 

是否大于或小于目标,等等,这将让你快速浏览数组,以查找对象是否存在与否。

我知道这是一个旧的post,但我想提供一个JQuery插件版本和我的代码。

 // Find the first occurrence of object in list, Similar to $.grep, but stops searching function findFirst(a,b){ var i; for (i = 0; i < a.length; ++i) { if (b(a[i], i)) return a[i]; } return undefined; } 

用法:

 var product = $.findFirst(arrProducts, function(p) { return p.id == 10 }); 

这个function是检查一个唯一的字段。 Arg 1:具有选定数据的数组Arg 2:检查Arg 3的键:必须“validation”的值

 function objectUnique( array, field, value ) { var unique = true; array.forEach(function ( entry ) { if ( entry[field] == value ) { unique = false; } }); return unique; }