简体   繁体   English

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

[英]Best way to check a JS object for matching values

I need to expand(from 2 to a maximum of 10) and optimize some model importing, but i just can't think of a good way to check a javascript object for matching values other than a ton of if statements, So i thought i would ask here and see if there are any experienced js devs that knows of a good, lightweight way to accomplish this.. 我需要扩展(从2到最大10)并优化一些模型导入,但是我想不出一种检查javascript对象是否匹配大量if语句以外的值的好方法,所以我想我会在这里问,看看是否有经验丰富的js开发人员知道实现此目标的好方法。

Basic structure: 基本结构:

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

(up to a maximum of 10 inputs, a.10Id & Id2) (最多10个输入,a.10Id和Id2)

Now, i need to check for matches.. 现在,我需要检查比赛。

If 1Id is the same as 2Id and 1Id2 is the same as 2Id2, only import the model once. 如果1Id与2Id相同,而1Id2与2Id2相同,则仅导入一次模型。

When there are only two model inputs, it's rather simple. 当只有两个模型输入时,这很简单。

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

But beyond that, you can imagine that it starts getting rather heavy with if statements to check how many and if any of them are the same.. 但是除此之外,您可以想象,如果使用if语句检查有多少个相同的语句,它会变得很繁重。

So to wrap it up, i'm basicly hoping that it is possible with some kind of function or algorythm, to check all xId and xId2 input values if they are matching with any of the others and then only send one of the matching inputs to the loader, thus avoiding importing the same model several times. 因此,要总结一下,我基本上希望可以使用某种函数或算法,检查所有xId和xId2输入值是否与其他任何值匹配,然后仅将匹配的输入之一发送到加载程序,从而避免多次导入同一模型。

There are a lot of questions left unanswered, so here is something that compares each Id[n] against the next Id[n+1]. 还有很多问题没有答案,因此这里将每个Id [n]与下一个Id [n + 1]进行比较。 It doesn't completely solve the problem, but should point you in the right direction. 它不能完全解决问题,但应为您指明正确的方向。

I had to change your object, because object properties can't start with a number. 我必须更改您的对象,因为对象属性不能以数字开头。 I also made some assumptions, such as the values are actually strings (because as you present them in your sample, they are actually variables). 我还作了一些假设,例如值实际上是字符串(因为在示例中显示它们时,它们实际上是变量)。

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'
};

The first thing I do is the Object.keys from a because that will allow me to iterate through all the keys without knowing ahead of time what they may be. 我要做的第一件事是来自aObject.keys ,因为这将允许我遍历所有键,而无需提前知道它们可能是什么。

var k1 = Object.keys(a);

I then pass the object and the keys into a function: 然后,我将对象和键传递给函数:

checkMatches(k1, a);

The function checks the object sequentially, comparing the first key to the second key, second key to the third key, and so on - pushing anything key that doesn't match the other in an array. 该函数按顺序检查对象,将第一个键与第二个键进行比较,将第二个键与第三个键进行比较,依此类推-将任何与另一个键不匹配的键推入数组中。 I console.log the keys involved in each comparison. console.log每个比较中涉及的键。 Here is the function. 这是功能。

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

Like I said, it doesn't solve your problem exactly - mostly because there are a lot of specifics that could change the final result. 就像我说的那样,它不能完全解决您的问题-主要是因为有很多细节可能会改变最终结果。

Here is a jsbin with it working as outlined. 这是一个jsbin,它按概述工作。

It sounds to me like you're looking simply to put your insertions into an array, and loop over the array each time. 在我看来,您只是想将插入的内容放入数组中,然后每次在数组中循环。 That will let you grow to any size, without the if statements getting out of hand. 这将使您可以扩展到任意大小,而不会失去if语句的控制权。

It would basically look like this: 基本上看起来像这样:

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

Maybe you're looking for something else, but based on the code you provided, this may be helpful. 也许您正在寻找其他东西,但是根据您提供的代码,这可能会有所帮助。

Good luck! 祝好运!

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

Final result. 最后结果。

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


};

Models are imported in sets of 2, 6 or 10. 模型以2、6或10组输入。

As previously mentioned "a" contains some other informations than just id's/id2's, I would have liked to use @whipdancer 's code to handle sending the id's to the newModel function but I had to handle it like this, otherwise it would require rewrites of my code that creates "a",which i am not interested in, and it's maximum 10 models anyhow, so i suppose this is Ok. 如前所述,“ 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);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM