我需要确定一个对象是否已经存在于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”数组包含了所有实例。
我现在正在寻找一个快速的解决方案来检查car1, car2, car3或car4的实例是否已经在carBrands数组中。
eg:
var contains = carBrands.Contains(car1); //<--- returns bool.
Car1和car4包含相同的数据,但它们是不同的实例,应该测试为不相等。
我是否需要在创建对象时添加散列之类的东西?或者在Javascript中有更快的方法来做到这一点。
我在这里寻找最快的解决方案,如果肮脏,所以它必须是;)在我的应用程序中,它必须处理大约10000个实例。
没有jquery
最近被FP bug咬了一口,阅读了许多关于函数式范式如何与Javascript完美契合的精彩描述
为了完整起见,我复制了代码,并提出了两种可以实现此功能的方法。
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)
}
你可以使用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"; });
为什么不使用javascript数组的indexOf方法呢?
看看这个:MDN indexOf Arrays
只是做的事:
carBrands.indexOf(car1);
它将返回car1的索引(在数组中的位置)。如果在数组中没有找到car1,它将返回-1。
http://jsfiddle.net/Fraximus/r154cd9o
Edit: Note that in the question, the requirements are to check for the same object referenced in the array, and NOT a new object. Even if the new object is identical in content to the object in the array, it is still a different object.
As mentioned in the comments, objects are passed by reference in JS and the same object can exist multiple times in multiple structures.
If you want to create a new object and check if the array contains objects identical to your new one, this answer won't work (Julien's fiddle below), if you want to check for that same object's existence in the array, then this answer will work. Check out the fiddles here and in the comments.
我将在数组上使用属性/值的泛型迭代器。不需要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;
}