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

时间:2016-02-03 21:56:34

标签: javascript optimization

我需要扩展(从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;
}

但除此之外,你可以想象它开始变得相当沉重,用if语句来检查它们中有多少以及它们是否相同......

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

3 个答案:

答案 0 :(得分:2)

有很多问题没有得到解答,所以这里有一个比较每个Id [n]和下一个Id [n + 1]的东西。它并没有完全解决问题,但应该指向正确的方向。

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

sudo apt-get install library

我做的第一件事就是来自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' }; 的{​​{1}},因为这样我就可以在不事先知道它们的情况下迭代所有键。

Object.keys

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

a

该函数按顺序检查对象,将第一个键与第二个键进行比较,将第二个键与第三个键进行比较,依此类推 - 推送任何与数组中的另一个键不匹配的键。我var k1 = Object.keys(a); 每个比较中涉及的密钥。这是功能。

checkMatches(k1, a);

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

Here is a jsbin with it working as outlined.

答案 1 :(得分:1)

听起来像你只是想把你的插入放入一个数组中,并且每次都在数组上循环。这将使你成长为任何规模,而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);

答案 2 :(得分:0)

最终结果。

typedef

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

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

//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 );
  }


};