是否有一种方法可以在JavaScript中返回两个数组之间的差异?
例如:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
是否有一种方法可以在JavaScript中返回两个数组之间的差异?
例如:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
当前回答
您可以使用一个公共对象并计算第一个数组中每个值的频率。对于第二个数组,减少公共对象中的值。然后遍历所有键并添加所有值大于1的键。
常量差值= (a1, a2) => { Var obj = {}; a1。forEach(obj[v] = (obj[v] || 0) + 1); a2。forEach(v => obj[v] = (obj[v] || 0) - 1); 返回对象 . keys (obj) .reduce((r,k) => { If (obj[k] > 0) r = r.concat (Array.from({长度:obj [k]}) .fill (k)); 返回r; }, []); }; const =结果不同([' a ', ' ', ' b ', ' c ', ' d '], [a, b]); console.log(结果);
其他回答
如果你想找出两个object数组之间的差异,你可以这样做:
let arrObj = [{id: 1},{id: 2},{id: 3}] let arrObj2 = [{id: 1},{id: 3}] let result = arrObj。filter(x => arrObj2.)每个(x2 => x2。Id == x.id) console.log(结果)
纯JavaScript
对于“差异”有两种可能的解释。我让你选你想要的。假设你有:
var a1 = ['a', 'b' ];
var a2 = [ 'b', 'c'];
If you want to get ['a'], use this function: function difference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } return result; } If you want to get ['a', 'c'] (all elements contained in either a1 or a2, but not both -- the so-called symmetric difference), use this function: function symmetricDifference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } for (i = 0; i < a2.length; i++) { if (a1.indexOf(a2[i]) === -1) { result.push(a2[i]); } } return result; }
斜线/下划线
如果你正在使用lodash,你可以使用_。差异(a1, a2)(上述情况1)或_。Xor (a1, a2)(情形2)
如果你使用的是Underscore.js,你可以使用_。情况1的差分(a1, a2)函数。
ES6 Set,用于非常大的数组
上面的代码适用于所有浏览器。然而,对于超过10,000个项目的大型数组,它变得相当慢,因为它有O(n²)的复杂度。在许多现代浏览器中,我们可以利用ES6 Set对象来加快速度。Lodash在可用时自动使用Set。如果你不使用lodash,使用下面的实现,灵感来自Axel Rauschmayer的博客文章:
function difference(a1, a2) {
var a2Set = new Set(a2);
return a1.filter(function(x) { return !a2Set.has(x); });
}
function symmetricDifference(a1, a2) {
return difference(a1, a2).concat(difference(a2, a1));
}
笔记
如果您关心-0、+0、NaN或稀疏数组,那么所有示例的行为都可能令人惊讶或不明显。(对于大多数用途来说,这并不重要。)
如果数组不是简单类型,则可以采用上面的答案之一:
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});
};
这种方法适用于复杂对象的数组。
如果你不关心原始数组,编辑它们没有问题,那么这是一个更快的算法:
let iterator = arrayA.values()
let result = []
for (entryA of iterator) {
if (!arrayB.includes(entryA)) {
result.push(entryA)
} else {
arrayB.splice(arrayB.indexOf(entryA), 1)
}
}
result.push(...arrayB)
return result
function diffArray(newArr, oldArr) {
var newSet = new Set(newArr)
var diff = []
oldArr.forEach((a) => {
if(!newSet.delete(a))diff.push(a)
})
return diff.concat(Array.from(newSet))
}