我有两个数组,如下:
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}
视为两个不同的对象,即使它们内部具有完全相同的属性和值。
在我的实际代码中,我有更复杂且具有更多属性的对象,但情况是一样的。
答案 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并再次扫描数组。