14

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

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

8 回答 8

23

小提琴

 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;
            }
        }
    }
于 2013-07-24T09:50:45.990 回答
6

除了使用两个循环之外,您还可以使用 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)
}
于 2019-04-11T21:10:38.040 回答
4

您的问题是,这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);
}

示例小提琴

于 2013-07-24T09:50:26.550 回答
3

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

if (a[i].name == b[j].name) {
    b.splice(j, 1);
    break;
}
于 2013-07-24T11:04:48.910 回答
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);
            }
        }
    }

小提琴演示

于 2013-07-24T09:48:07.753 回答
1

在对象数组中比较和删除。对象数据类型的数组通常可能是typeOf是对象。所以我们需要转换成JSON字符串化然后检查条件..

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

于 2014-10-02T18:39:31.220 回答
1
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以获取 Javascript 中的数组数据操作示例

于 2020-01-02T12:33:32.167 回答
0

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

于 2013-07-24T09:52:13.630 回答