比较两个对象数组,并删除第二个具有相同属性值的项目

时间:2013-07-24 09:42:06

标签: javascript arrays object

我需要做的就是比较两个对象数组,并删除第二个具有相同属性值的项目。例如:

var a = [{'name':'bob', 'age':22}, {'name':'alice', 'age':12}, {'name':'mike', 'age':13}];
var b = [{'name':'bob', 'age':62}, {'name':'kevin', 'age':32}, {'name':'alice', 'age':32}];

function remove_duplicates(a, b) {
    for (var i = 0, len = a.length; i < len; i++) {
        for (var j = 0, len = b.length; j < len; j++) {
            if (a[i].name == b[j].name) {
                b.splice(j, 1);
            }
        }
    }

    console.log(a);
    console.log(b);

}

console.log(a);
console.log(b);

remove_duplicates(a,b);

我无法理解为什么这不起作用而是给出:

Uncaught TypeError: Cannot read property 'name' of undefined

我的预期是b中的以下内容:

[{'name':'kevin', 'age':32}];

8 个答案:

答案 0 :(得分:15)

<强> FIDDLE

 for (var i = 0, len = a.length; i < len; i++) { 
        for (var j = 0, len2 = b.length; j < len2; j++) { 
            if (a[i].name === b[j].name) {
                b.splice(j, 1);
                len2=b.length;
            }
        }
    }

答案 1 :(得分:3)

找到匹配项时,您只需要打破内部循环:

if (a[i].name == b[j].name) {
    b.splice(j, 1);
    break;
}

答案 2 :(得分:2)

您的问题是,splice()将更改数组的长度,以便您的预先计算的len值太大,并且您尝试访问未定义元素的循环内部。

可能的解决方案是使用filter()方法:

function remove_duplicates(a, b) {

  b = b.filter( function( item ) {
      for( var i=0, len=a.length; i<len; i++ ){
          if( a[i].name == item.name ) {
              return false;
          }
      }
      return true;
  });

  console.log(a);
  console.log(b);
}

Example Fiddle

答案 3 :(得分:2)

除了使用两个循环,您还可以使用findIndex函数:

for (var i = 0, len = a.length; i < len; i++) {
    var ItemIndex = b.findIndex(b => b.name === a[i].name);

    a.splice(ItemIndex, 1)
}

或者如果您想不使用循环就完全走,则可以使用forEach函数

a.forEach(function(item, index, array) {
    var ItemIndex = b.findIndex(b => b.name === item.name);

    a.splice(ItemIndex, 1)
}

答案 4 :(得分:1)

试试这个:

您正在从0开始循环。

for (var i = 0, len = a.length; i < len; i++) {
        for (var j = 0, len = b.length; j < len-1; j++) {
            if (a[i].name == b[j].name) {
                b.splice(j, 1);
            }
        }
    }

Fiddle Demo

答案 5 :(得分:0)

根本原因是你在for循环中直接拼接数组b中的项目,而pre条件是a和b具有相同数量的项目。

答案 6 :(得分:0)

比较并删除对象数组。对象数据类型的典型数组可能是typeOf是object.So我们需要转换为JSON stringify然后检查条件..

for(var i=0; i < a.length; i++) {
                    for(var j=0; j < b.length; j++) {
                        if(JSON.stringify(a[i])  == JSON.stringify(b[j])) {
                            a.splice(i, 1);
                        }
                    }
                }

答案 7 :(得分:0)

let A = [
  {name: 'a', age: 20},
  {name: 'b', age: 30},
  {name: 'c', age: 10},
]

let B = [
  {name: 'a', age: 20},
  {name: 'b', age: 40},
  {name: 'd', age: 10},
  {name: 'e', age: 20},
  {name: 'f', age: 10},
]

const compareName = (obj1, obj2)=>{
  return (obj1.name === obj2.name);
}

const compareAll = (obj1, obj2)=>{
  return (obj1.name === obj2.name && obj1.age=== obj2.age);
}

let output = B.filter(b=>{
  let indexFound = A.findIndex(a => compareName(a, b));
  return indexFound == -1;
})

根据要删除的对象而定:

  1. compareName:删除具有通用名称的对象
  2. compareAll:删除名称和年龄相同的对象

要查找公用对象列表,只需添加使用return index != -1

PS:请参阅我的Github中的Java数组数据操作示例