是否有一种方法可以在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"]
当前回答
这个问题很老了,但仍然是javascript数组减法的热门问题,所以我想添加我正在使用的解决方案。适用于以下情况:
var a1 = [1,2,2,3]
var a2 = [1,2]
//result = [2,3]
下面的方法将产生预期的结果:
function arrayDifference(minuend, subtrahend) {
for (var i = 0; i < minuend.length; i++) {
var j = subtrahend.indexOf(minuend[i])
if (j != -1) {
minuend.splice(i, 1);
subtrahend.splice(j, 1);
}
}
return minuend;
}
需要注意的是,该函数不包括减数中没有被减数的值:
var a1 = [1,2,3]
var a2 = [2,3,4]
//result = [1]
其他回答
var arrayDifference = function(arr1, arr2){
if(arr1 && arr1.length){
if(arr2 && arr2.length > 0){
for (var i=0, itemIndex; i<arr2.length; i++){
itemIndex = arr1.indexOf(arr2[i]);
if(itemIndex !== -1){
arr1.splice(itemIndex, 1);
}
}
}
return arr1;
}
return [];
};
arrayDifference([1,2,3,4,5], [1,5,6]);
类似于Ian Grainger的解决方案(但在打字稿中):
function findDiffs(arrayOne: string[], arrayTwo: string[]) {
let onlyInArrayOne = []
let onlyInArrayTwo = []
let share = []
let [arrayOneCopy, arrayTwoCopy] = [[...arrayOne], [...arrayTwo]]
arrayOneCopy.sort(); arrayTwoCopy.sort()
while (arrayOneCopy.length !== 0 && arrayTwoCopy.length !== 0) {
if (arrayOneCopy[0] == arrayTwoCopy[0]) {
share.push(arrayOneCopy[0])
arrayOneCopy.splice(0, 1)
arrayTwoCopy.splice(0, 1)
}
if (arrayOneCopy[0] < arrayTwoCopy[0]) {
onlyInArrayOne.push(arrayOneCopy[0])
arrayOneCopy.splice(0, 1)
}
if (arrayOneCopy[0] > arrayTwoCopy[0]) {
onlyInArrayTwo.push(arrayTwoCopy[0])
arrayTwoCopy.splice(0, 1)
}
}
onlyInArrayTwo = onlyInArrayTwo.concat(arrayTwoCopy)
onlyInArrayOne = onlyInArrayOne.concat(arrayOneCopy)
return {
onlyInArrayOne,
onlyInArrayTwo,
share,
diff: onlyInArrayOne.concat(onlyInArrayTwo)
}
}
// arrayOne: [ 'a', 'b', 'c', 'm', 'y' ]
// arrayTwo: [ 'c', 'b', 'f', 'h' ]
//
// Results:
// {
// onlyInArrayOne: [ 'a', 'm', 'y' ],
// onlyInArrayTwo: [ 'f', 'h' ],
// share: [ 'b', 'c' ],
// diff: [ 'a', 'm', 'y', 'f', 'h' ]
// }
困难的方法(如果你想做一些比.indexOf更奇特的东西)
var difference = function (source, target) {
return source.reduce(function (diff, current) {
if (target.indexOf(current) === -1) {
diff.push(current);
}
return diff;
}, []);
}
简单的方法
var difference = function (source, target) {
return source.filter(function (current) {
return target.indexOf(current) === -1;
});
}
所选的答案只对了一半。您必须比较数组的两种方式才能得到完整的答案。
const ids_exist = [
'1234',
'5678',
'abcd',
]
const ids_new = [
'1234',
'5678',
'efjk',
'9999',
]
function __uniq_Filter (__array_1, __array_2) {
const one_not_in_two = __array_1.filter(function (obj) {
return __array_2.indexOf(obj) == -1
})
const two_not_in_one = __array_2.filter(function (obj) {
return __array_1.indexOf(obj) == -1
})
return one_not_in_two.concat(two_not_in_one)
}
let uniq_filter = __uniq_Filter(ids_exist, ids_new)
console.log('uniq_filter', uniq_filter) // => [ 'abcd', 'efjk', '9999' ]
如果你不关心原始数组,编辑它们没有问题,那么这是一个更快的算法:
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