检查 JS 对象是否匹配值的最佳方法

Best way to check a JS object for matching values

本文关键字:最佳 方法 JS 对象 是否 检查      更新时间:2023-09-26

我需要扩展(从 2 个扩展到最多 10 个(并优化一些模型导入,但我只是想不出一个好方法来检查 javascript 对象是否匹配值,而不是大量的 if 语句,所以我想我会在这里问一下,看看是否有任何有经验的js开发人员知道一个好的,轻量级的方式来实现这一目标。

基本结构:

//a is the object, it contains some basic, unrelated information and
//either 2, 6 or 10 id's & id2's
//unused id's have a value of 0.
//Sorry for the faulty variables, i was in a rush and just needed to show that xid & xid2 fit together and yid & yid2 fit together, etc.
//input 1
a.1Id = x; //Primary, Desides the actual model to import
a.1Id2 = y; //Secondary, Desides version of the model, specific colours, features, etc
//input 2
a.2Id = z;
a.2Id2 = x;
(最多 10 个

输入,a.10Id & Id2(

现在,我需要检查匹配项。

如果 1Id 与 2Id 相同,1Id2 与 2Id2 相同,则仅导入一次模型。

当只有两个模型输入时,它相当简单。

//the import is not actually structured as var importX, 
//they are pushed to another object and then the loader loads each of them with a for..loop
if (a.1Id === a.2Id && a.1Id2 === a.2Id2){
  var import1 = a.1Id;
  var import12 = a.1Id2;
} else {
  var import1 = a.1Id;
  var import12 = a.1Id2;
  var import2 = a.2Id;
  var import22 = a.2Id2;
}

但除此之外,你可以想象它开始变得相当繁重,如果语句来检查有多少以及它们中的任何一个是否相同。

因此,总结一下,我基本上希望可以使用某种函数或算法来检查所有 xId 和 xId2 输入值是否与其他任何值匹配,然后只将其中一个匹配的输入发送到加载器,从而避免多次导入相同的模型。

还有很多问题没有答案,所以这里有一些东西将每个 Id[n] 与下一个 Id[n+1] 进行比较。 它不能完全解决问题,但应该为你指明正确的方向。

我不得不更改您的对象,因为对象属性不能以数字开头。 我还做了一些假设,例如值实际上是字符串(因为当您在示例中呈现它们时,它们实际上是变量(。

var a = {
  Id1_: '1',
  Id1_2: '1a',
  Id2_: '1',
  Id2_2: '2a',
  Id3_: '3',
  Id3_2: '3a',
  Id4_: '1',
  Id4_2: '1a',
  Id5_: '2',
  Id5_2: '2a',
  Id6_: '3',
  Id6_2: '3a',
  Id7_: '2',
  Id7_2: '2a',
  Id8_: '3',
  Id8_2: '3a',
  Id9_: '1',
  Id9_2: '1a',
  Id10_: '1',
  Id10_2: '2a'
};

我做的第一件事是aObject.keys,因为这将允许我遍历所有密钥,而无需提前知道它们可能是什么。

var k1 = Object.keys(a);

然后,我将对象和键传递给一个函数:

checkMatches(k1, a);

该函数按顺序检查对象,将第一个键与第二个键、第二个键与第三个键进行比较,依此类推 - 推送数组中与另一个键不匹配的任何键。我console.log每次比较中涉及的键。 这是函数。

function checkMatches(k, o){
  var results = [];
  var s = "Id", f = "_";
  var nextId = 2;
  var idCnt = 0;
  var propt = "";
  for (var i = 0; i < k.length; i++){ 
    idCnt += 1;
    if (idCnt === 3) {
      idCnt = 1;
      nextId += 1;
    }
    propt = s + nextId + f;
    if (idCnt === 2) {
      propt += "2";    
    } 
    console.log(k[i] + ": " + o[k[i]] + " vs " + propt + ": " + o[propt]);
    if (o[k[i]] !== o[propt]) {
      results.push({ id: k[i], value: o[k[i]] });
    }
  } 
  return results;
}

就像我说的,它不能完全解决你的问题 - 主要是因为有很多细节可能会改变最终结果。

这是一个 jsbin,它按概述工作。

在我看来,您只是想将插入内容放入数组中,然后每次都遍历数组。 这将使您增长到任何大小,而不会使 if 语句失控。

它基本上看起来像这样:

var imported = [];
var processImport = function (obj) {
  // there are better ways, but this will work:
  var found = false;
  for (var i = 0; i < imported.length; ++i) {
    if (imported[i].id == obj.id && imported[i].id2 == obj.id2) {
      found = true;
      break;
    }
  }
  if (!found) {
    imported.push({
      id: obj.id,
      id2: obj.id2
    });
  }
}

也许您正在寻找其他内容,但根据您提供的代码,这可能会有所帮助。

祝你好运!

var imported = [];
var processImport = function (obj) {
  // there are better ways, but this will work:
  var found = false;
  for (var i = 0; i < imported.length; ++i) {
    if (imported[i].id == obj.id && imported[i].id2 == obj.id2) {
      found = true;
      break;
    }
  }
  if (!found) {
    imported.push({
      id: obj.id,
      id2: obj.id2
    });
  }
}
var toImport = [{
  id: 1,
  id2: 1
}, {
  id: 1,
  id2: 2
}, {
  id: 2,
  id2: 1
}, {
  id: 1,
  id2: 1
}];
for (var j = 0; j < toImport.length; ++j) {
  processImport(toImport[j]);
}
alert(imported.length);

最终结果。

//Models.
var mIds = []; //Store id's to import
function Model() {
  this.Id = 0;
  this.Id2 = 0;
}
function newModel(data) {
  var found = false;
  for (var i = 0; i < mIds.length; i++) {
    if (mIds[i].Id === data.Id && mIds[i].Id2 === data.Id2) {
      found = true;
      break;
    }
  }
  if (!found) {
    var model = new Model();
    model.Id = data.Id;
    model.Id2 = data.Id2;
    mIds.push( model );
  }

};

模型以 2、6 或 10 个为一组导入。

如前所述,"a"包含一些其他信息,而不仅仅是id/id2的信息,我本来想使用 @whipdancer 的代码来处理将 id 发送到 newModel 函数,但我必须这样处理它,否则它需要重写我的代码来创建"a",我不感兴趣,无论如何它最多有 10 个模型,所以我想这是可以的。

if (a.count > 1) { //atleast 2 models
  var data1 = {};
  data1.Id = a.Id1;
  data1.Id2 = a.Id1_2;
  newModel(data1);
  var data2 = {};
  data2.Id = a.Id2;
  data2.Id2 = a.Id2_2;
  newModel(data2);
  //delete data1;
  //delete data2;
}
if (a.count > 5) { //atleast 6 models
  var data3 = {};
  data3.Id = a.Id3;
  data3.Id2 = a.Id3_2;
  newModel(data3);
  var data4 = {};
  data4.Id = a.Id4;
  data4.Id2 = a.Id4_2;
  newModel(data4);
  var data5 = {};
  data5.Id = a.Id5;
  data5.Id2 = a.Id5_2;
  newModel(data5);
  var data6 = {};
  data6.Id = a.Id6;
  data6.Id2 = a.Id6_2;
  newModel(data6);
}
if (a.count > 9) { //10 models
  var data7 = {};
  data7.Id = a.Id7;
  data7.Id2 = a.Id7_2;
  newModel(data7);
  var data8 = {};
  data8.Id = a.Id8;
  data8.Id2 = a.Id8_2;
  newModel(data8);
  var data9 = {};
  data9.Id = a.Id9;
  data9.Id2 = a.Id9_2;
  newModel(data9);
  var data10 = {};
  data10.Id = a.Id10;
  data10.Id2 = a.Id10_2;
  newModel(data10);
}