是否有一种方法可以在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"]
当前回答
对称和线性复杂度。需要ES6。
function arrDiff(arr1, arr2) {
var arrays = [arr1, arr2].sort((a, b) => a.length - b.length);
var smallSet = new Set(arrays[0]);
return arrays[1].filter(x => !smallSet.has(x));
}
其他回答
根据之前的答案…取决于你是想要一个高效的还是“漂亮的联机”解决方案。
一般有三种方法……
"manual iterative" (using indexOf) - naive with O(n2) complexity (slow) var array_diff_naive = function(a,b){ var i, la = a.length, lb = b.length, res = []; if (!la) return b; else if (!lb) return a; for (i = 0; i < la; i++) { if (b.indexOf(a[i]) === -1) res.push(a[i]); } for (i = 0; i < lb; i++) { if (a.indexOf(b[i]) === -1) res.push(b[i]); } return res; } "abstract iterative" (using filter and concat library methods) - syntactic sugar for manual iterative (looks nicer, still sucks) var array_diff_modern = function(a1,a2){ return a1.filter(function(v) { return !a2.includes(v); } ) .concat(a2.filter(function(v) { return !a1.includes(v);})); } "using hashtable" (using object keys) - much more efficient - only O(n), but has slightly limited range of input array values var array_diff_hash = function(a1,a2){ var a = [], diff = []; for (var i = 0; i < a1.length; i++) { a[a1[i]] = true; } for (var i = 0; i < a2.length; i++) { if (a[a2[i]]) { delete a[a2[i]]; } else { a[a2[i]] = true; } } for (var k in a) { diff.push(k); } return diff; }
在jsperf上可以看到 https://jsperf.com/array-diff-algo
如果不使用hasOwnProperty,那么我们有不正确的元素。例如:
[1,2,3].diff([1,2]); //Return ["3", "remove", "diff"] This is the wrong version
我的版本:
Array.prototype.diff = function(array2)
{
var a = [],
diff = [],
array1 = this || [];
for (var i = 0; i < array1.length; i++) {
a[array1[i]] = true;
}
for (var i = 0; i < array2.length; i++) {
if (a[array2[i]]) {
delete a[array2[i]];
} else {
a[array2[i]] = true;
}
}
for (var k in a) {
if (!a.hasOwnProperty(k)){
continue;
}
diff.push(k);
}
return diff;
}
如果数组不是简单类型,则可以采用上面的答案之一:
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});
};
这种方法适用于复杂对象的数组。
我同意@luis-sieira的解决方案
我创建了位自解释函数,便于初学者一步一步理解:
function difference(oneArr, twoArr){
var newArr = [];
newArr = oneArr.filter((item)=>{
return !twoArr.includes(item)
});
console.log(newArr)
let arr = twoArr.filter((item)=>{
return !oneArr.includes(item)
});
newArr = newArr.concat(arr);
console.log(newArr)
}
difference([1, 2, 3, 5], [1, 2, 3, 4, 5])
var compare = array1.length > array2.length ? array1 : array2;
var compareWith = array1.length > array2.length ? array2 : array1;
var uniqueValues = compareWith.filter(function(value){
if(compare.indexOf(vakye) == -1)
return true;
});
这将检查数组中哪个更大,然后进行比较。