获取具有相同对象的数组之间的差异

时间:2017-12-10 16:58:30

标签: javascript arrays

我有两个数组,如下:

var a = [
    {id: 1}, {id: 2}, {id: 1}, {id: 3}
];

var b = [
    {id: 1}, {id: 3}
];

我希望获得数组a具有的元素和数组b不具备的元素。预期结果是:

[
    {id: 1}, {id: 2}
]

我试过了:

a.filter(x => b.indexOf(x) == -1);

而且:

a.filter(x => new Set(b).has(x) == false);

这两个问题是它将来自数组A的{id: 2}和来自数组B的{id: 2}视为不同的对象,因此这两行代码只返回完整的数组A.

另一个困难是,我需要将{id: 1}{id: 1}视为两个不同的对象,即使它们内部具有完全相同的属性和值。

在我的实际代码中,我有更复杂且具有更多属性的对象,但情况是一样的。

2 个答案:

答案 0 :(得分:1)

您可以使用一个集合并返回已过滤的数组,而不返回该组ID的值。



var a = [{ id: 1 }, { id: 2 }, { id: 1 }, { id: 3 }],
    b = [{ id: 2 }, { id: 3 }],
    s = new Set(b.map(({ id }) => id)),
    result = a.filter(({ id }) => !s.has(id));
    
console.log(result);




答案 1 :(得分:1)

我最终得到了这个:

function differenceOf(arr1, arr2) {
  var differences = $.extend(true, [], arr1); // creates clone
  var arr2Duplicate = $.extend(true, [], arr2);
arr2Loop:
  for(var i = 0; i < arr2Duplicate.length; i++) {
      var obj2 = arr2Duplicate[i];
      if(obj2 == null) continue;
differencesLoop:
      for(var j = 0; j < differences.length; j++) {
          var obj1 = differences[j];
          if(obj1 == null) continue;
          if(obj1.id == obj2.id) {
            differences.splice(j, 1);
            arr2Duplicate.splice(i, 1);
            i = -1;
            j = -1;
            break differencesLoop;
          }
      }
  }
  return differences;
}

我克隆了两个数组以供将来操作,因此将删除引用并且不会影响原始数组。我将第一个数组设置为differences数组,因此我可以删除出现在另一个数组中的元素。

我遍历第二个数组,然后在该循​​环内迭代第一个数组。然后,我检查是否有相同的ID;如果是这样,那么我在两个数组中都找到了一个元素,所以我只是从第一个数组中删除它。我还从第二个数组中删除元素以防止重复比较,然后我打破循环以防止更多删除具有相同ID的元素。

当我删除元素时,循环仍在继续,最终它将到达该元素曾经的空槽,所以我检查它是否为空;如果是这样,请跳过并继续。

在两个循环完成之后,我留下了一个具有不同元素的数组,而不管具有相同属性的元素。

编辑:我将jQuery的每个循环更改为标准for循环,因为当我试图突破内循环时,它也会突破外循环。我通过添加那些修复了破坏问题的GOTO标签来解决这个问题。

当我检测到重复时,我还将索引重置为-1,因为当循环继续时,索引将递增并跳过对象,从而导致数据不正确。我将其重置为-1,这样当代码块完成时,它将增加回0并再次扫描数组。