JavaScript -- 在对象数组中查找匹配对象

3

我正在尝试在对象数组中搜索一个对象。

注意,vals和recs对象将是动态的。

var vals = {ID: "4", LOC: "LA", SEQ: "1"};

var recs = [
  {ID:"4", LOC:"LA", SEQ:"1"},
  {ID:"4", LOC:"NY", SEQ:"1"},
  {ID:"4", LOC:"CHI",SEQ:"1"}

];

现在我需要检查 vals 中的每个键值对是否已经存在于 recs 中。在这种情况下,recs[0] 是 vals 的一个完全匹配。
以下是我的尝试:
var vals =  {ID: "4", LOC: "LA", SEQ: "1"};


var recs = [
  {ID:"4", LOC:"LA", SEQ:"1"},
  {ID:"3", LOC:"NY", SEQ:"2"},
  {ID:"2", LOC:"CHI",SEQ:"3"}

];


for(var i = 0; i<recs.length; i++){  
    if(recs[i]["ID"] == vals["ID"] && recs[i]["LOC"] == vals["LOC"] && recs[i]["SEQ"] == vals["SEQ"]){
      console.log(true);
    }
    else{
      console.log(false);
    }  
}

上面的代码只能工作是因为我已经硬编码了vals对象中的键。实际上,VALS对象(和recs)将是动态的,具有X个键值对。
那么我该如何修改我的for循环来适应动态的vals对象呢?
谢谢!

1
所以循环遍历键。var keys = Object.keys(vals); - epascarello
从经验丰富的人来看,Object.keys()非常快,因此比较每个对象键数组的长度将是一种快速消除不匹配项的方法。将这些键排序并连接成字符串提供了快速的成员资格比较。如果这两个快速测试都通过了,那么就迭代并比较值。当然,如果性能不重要,只需执行两个未过滤的嵌套循环和KISS即可。 - dandavis
问题是有关 Vue 的。{a:1} 是否描述了 {a:1,b:2}? 它应该返回第一个结果,所有匹配项还是一个布尔值? - dandavis
6个回答

1
你需要将其分成两个循环,一个用于数组中的每个对象,另一个用于对象中的每个键:
for(var i = 0; i<recs.length; i++){  
  var found = false
  for(var key in recs[i]) {
    if(recs[i].hasOwnProperty(key)){
      if(recs[i][key] != vals[key]){
        found = true
      }
    }
  console.log(found)
}
< p > hasOwnProperty 调用将确保如果对象没有该键,它不会中断。


vals.key 是从哪里来的?你需要使用 vals[key] 等。 - dandavis

1
for(var i = 0; i<recs.length; i++) {  
    for (var prop in object) {
       if (recs[i][prop] != vals[prop]) {
           console.log(false);
           return;
       }

    }
    //check from both sides
    for (var prop in vals) {
       if (recs[i][prop] != vals[prop]) {
           console.log(false);
           return;
       }

    }
    console.log(true);


}

形状不匹配将会在此模式下抛出异常。获取属性时要小心迭代的内容。 - dandavis

1

试试这个:

for (var i = 0; i < recs.length; i++) {  
  var found = true;
  for (var p in vals) {
    if (vals.hasOwnProperty(p)) {
      if (recs[i][p] !== vals[p]) {
        found = false;
        break;
      }
    }
  }
  console.log(found);
}

1
给我一个 break 以提高性能。 - dandavis

1
您可以迭代键; 大致如下:

var vals = {  ID: "4",  LOC: "LA",  SEQ: "1", REGION: "USA" };


var recs = [{    ID: 4,    LOC: "LA",    SEQ: "1",    REGION: "USA"  },
            {    ID: 3,    LOC: "NY",    SEQ: "2",    REGION: "USA"  },
            {    ID: 2,    LOC: "CHI",    SEQ: "3",    REGION: "USA" }

];

var isSame = true;

for (var i = 0; i < recs.length; i++) {
  console.log( i + '----------------' );
  var isSame = true;
  
  // get the keys of the record
  var keys = Object.keys(recs[i]);

  for (var j = 0; j < keys.length; j++) {
    
    var key = keys[j];
    var record = recs[i] 
    
    console.log( key + ": " + record[key] + '=' + vals[key] );   
    
    if (record[key] != vals[key] ) {                                
        isSame = false;// not equal
        break;
    }
  }

  console.log('isSame: ' + isSame );
  console.log('------------------' );
}


可能希望记忆keys[j]和/或recs[i],因为它们经常被使用以缩短并加快代码。 - dandavis
好的,我回到我的桌子前会更新答案...谢谢@dandavis - blurfus

0

你可以尝试这个:

function myFind(recs, vals) {
    return recs.some(function(obj) {
        for (var x in obj)
            if (x in vals && obj[x] != vals[x])
                return false;
        return true;
    });
}

var recs = [
    {ID:4, LOC:"LA", SEQ:"1", USA:"USA"},
    {ID:3, LOC:"NY", SEQ:"2", USA:"USA"},
    {ID:2, LOC:"CHI",SEQ:"3", USA:"USA"}
];

var vals =  {ID: "4", LOC: "LA", SEQ: "1"};

if (myFind(recs, vals)) {
    alert('found');
} else {
    alert('not found');
}

希望能有所帮助。

这不会找到该项。对象引用不同。 - Evan Trimboli
@EvanTrimboli。我没有看到recs的第二个声明,对此很抱歉,我已经更新了。 - user4227915
那个编辑也找不到值。引用仍然不同,而且还会导致在“recs”中改变值的缺点。 - Evan Trimboli
@EvanTrimboli。奇怪,这里可以运行,我会添加一个片段。 - user4227915
你为什么要使用 delete - dandavis
@dandavis。起初我以为需要删除,但是有更好的方法,谢谢 :) - user4227915

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接