我需要确定一个对象是否已经存在于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


当前回答

尝试Array.prototype.some ()

MDN Array.prototype.some


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

其他回答

编辑05/18/2022

使用ES6最简单的方法:

const arrayContainsObject = <T extends Record<string, unknown>>(array: T[], object: T) => {
  return array.some(item => Object.keys(item).every(key => item[key] === object[key]))
}

像这样使用:

const arr = [{
  prop1: 'value1',
  prop2: 'value2'
}]
const obj1 = {
  prop1: 'value1',
  prop2: 'value2'
}
const obj2 = {
  prop2: 'value2',
  prop1: 'value1'
}
const obj3 = {
  prop0: 'value0',
  prop1: 'value1'
}
arrayContainsObject(arr, obj1) // true
arrayContainsObject(arr, obj2) // true, even when props are arranged in different order
arrayContainsObject(arr, obj3) // false


之前的答案,不要使用(因为道具在对象中的顺序需要相同)

const arr = [{
  prop: 'value'
}]
const obj = {
  prop: 'value'
}
arr.some((e) => Object.entries(e).toString() === Object.entries(obj).toString()) // true

可以这样说:

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。如果你后来扩展到使用对象来存储这些其他car对象,而不是使用数组,你可以使用这样的东西:

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

    return false;
}

这种方法也适用于数组,但是当用于数组时,它会比第一种方法慢一些。

如果可能的话,使用es6

carBrands.filter(carBrand => carBrand.name === carX.name).length > 0

如果这是真的,那就有相似之处

这里许多答案的问题是,它们不会在数组中找到等于另一个对象的对象。它们只会在数组中搜索有指针指向的EXISTING对象。

快速修复使用lodash查看是否ANY相等对象在数组中:

import _ from 'lodash';
_.find(carBrands, car1); //returns object if true, undefined if false

工作活塞使用此方法:https://plnkr.co/edit/y2YX9o7zkQa2r7lJ

你可以尝试基于属性对数组进行排序,如下所示:

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

大于或小于目标,等等,这将让您快速遍历数组以查找对象是否存在。