将对象与对象数组进行比较

Comparing an object to an array of objects

我有一个 JavaScript 对象,我试图将其与对象数组进行比较:

var builtVehicle = {pattern: "../images/fire1192015.png", 
vehicle: "../images/van1192015.png", 
wheel: "../images/wheels3.png"};

var createdVehicles = [
{pattern:"../images/checkerboard1192015.png",       
vehicle:"../images/car1192015.png", wheel:"../images/wheels1.png"}, 
{pattern:"../images/fire1192015.png", vehicle:"../images/truck1192015.png",     
wheel:"../images/wheels4.png"},]

我试图遍历 JavaScript 对象和 createdVehicles 对象数组以寻找完全匹配。如果没有完全匹配,我想将 builtVehicle 对象添加到 createdVehicles 数组。我的想法是将数组中的每个 key/value 对对象与 builtVehicle 对象进行比较,但是我在提取数组中的 key/value 对时遇到了一些问题。我的循环看起来像这样:

for(var key in builtVehicle) {
    console.log('builtVehicle key: ' + key + '\n' + 'builtVehicle value: ' +     
builtVehicle[key]);
}


for(var b=0; b < createdVehicles.length; b++){
    alert(createdVehicles[b]);
}

这是最好的方法吗?我也在研究 2D 数组来实现这一点,但我们不胜感激任何建议。谢谢!

如果你可以改变数据结构,像这样的东西可能会更好,这取决于你要做什么 createdVehicles 以及它是否需要是一个数组。

// indexed by id of the vehicle, this could be a model number or something instead, but just need some identifying key for comparison.
// structure of item: { identifyingKey : vehicleObject }
createdVehicles = {
  1 : { ... },
  2 : { ... }
 }

if (!createVehicles.hasOwnProperty(builtVehicle.id)) {
  createdVehicles[builtVehicle.id] = builtVehicle;
}

如果您受制于约束,最好采用直接的方法并遍历数组。评论是正确的,因为旧方法假设车辆是基于一把钥匙的。这里创建了一个函数来进行 ddper 对象比较,然后用它来检查 vehicle 数组中的匹配项。如果有匹配项,我们就会退出,如果没有匹配项,则匹配项保持为假,我们知道在循环结束后将其添加到数组中。这有点沉重和冗长,但没有库,这应该可以工作。很抱歉语法错误之类的,在工作中所以尝试快速完成此操作。

//if you have access to underscore you can use _.size(obj) instead
// otherwise having access ot the size of the object helps, idk how people
// feel about touching the object protoype itself, but this is quick and dirty
Object.prototype.size = function(obj) {
  var size = 0, key;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) size++;
  }
  return size;
};

var match = false;

var isVehicle = function(builtVehicle, testVehicle) {
  if (builtVehicle.size() !== testVehicle.size()) {
     return false;
  }

  for (key in builtVehicle) {
    if (!testVehicle.hasOwnProperty[key]) {
      return false;
    }
  }

  return true;
}

for (var i = 0, len = createdVehicles.length; i < len; i++) {
  var testVehicle = createdVehicles[i],
      match = isVehicle(builtVehicle, testVehicle);

   //if there was a match break out
   if (match) {
     break;
   }
}

if (!match) {
  createdVehicles.push(builtVehicle);
}   

因为人们提到了下划线,如果您可以访问它,您可以执行以下操作:

for (var i = 0, len = createdVehicles.length; i < len; i++) {
  var testVehicle = createdVehicles[i],
      match = _.isEqual(builtVehicle, testVehicle);

   //if there was a match break out
   if (match) {
     break;
   }
}

if (!match) {
  createdVehicles.push(builtVehicle);
}

我不能说这是最好的方法。最终,我会像@Brodie 说的那样改变数据结构。否则你可以做这样的事情......

var builtVehicle = {
  pattern: "../images/fire1192015.png", 
  vehicle: "../images/van1192015.png", 
  wheel: "../images/wheels3.png"
};

var createdVehicles = [
{
  pattern:"../images/checkerboard1192015.png",       
  vehicle:"../images/car1192015.png", 
  wheel:"../images/wheels1.png"
}, 
{
  pattern:"../images/fire1192015.png", 
  vehicle:"../images/truck1192015.png",     
   wheel:"../images/wheels4.png"
}
];


var matchVehicle = function (vehicle, stack) {

  var i=0;

  for (i; i < stack.length; i+=1) {

      // if you have an id, thats even better because you don't have to test all of this, otherwise what makes it unique? a combo of everything?
      if ((vehicle.pattern === stack[i].pattern) && (vehicle.vehicle === stack[i].vehicle) && (vehicle.wheel === stack[i].wheel)) {
          return stack[i]; // returns the matching vehicle.
      }
  }
  // Will push the vehicle if it didn't match
  stack.push(vehicle);

};

console.log(matchVehicle(builtVehicle, createdVehicles));