是否有一种方法可以在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"]
当前回答
求两个没有重复项的数组的差值:
function difference(arr1, arr2){
let setA = new Set(arr1);
let differenceSet = new Set(arr2.filter(ele => !setA.has(ele)));
return [...differenceSet ];
}
1.difference([2,2,3,4],[2,3,3,4])将返回[]
2.difference([1,2,3],[4,5,6])将返回[4,5,6]
3.difference([1,2,3,4],[1,2])返回[]
4.difference([1,2],[1,2,3,4])将返回[3,4]
注意:上述解决方案要求始终将较大的数组作为第二个参数发送。要找到绝对差值,首先需要找到两者的较大数组,然后对它们进行处理。
求两个不存在重复项的数组的绝对差值:
function absDifference(arr1, arr2){
const {larger, smaller} = arr1.length > arr2.length ?
{larger: arr1, smaller: arr2} : {larger: arr2, smaller: arr1}
let setA = new Set(smaller);
let absDifferenceSet = new Set(larger.filter(ele => !setA.has(ele)));
return [...absDifferenceSet ];
}
1. absdifference((2, 2, 3, 4),[2、3、3、4])将返回[]
2. absdifference([1, 2, 3],[4、5、6])将返回(4、5、6)
3. absdifference([1、2、3、4],[1,2])将返回(3、4)
4. absdifference([1, 2],[1、2、3、4])将返回(3、4)
请注意这两个解决方案中的示例3
其他回答
function diff(arr1, arr2) {
var filteredArr1 = arr1.filter(function(ele) {
return arr2.indexOf(ele) == -1;
});
var filteredArr2 = arr2.filter(function(ele) {
return arr1.indexOf(ele) == -1;
});
return filteredArr1.concat(filteredArr2);
}
diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]
在这种情况下,您可以使用Set。它针对这种操作(并、交、差)进行了优化。
确保它适用于你的案例,一旦它不允许重复。
var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);
a.difference(b)
// -> Set{1,3,5,7,9}
只是想…为了一个挑战;-)这个工作…(对于字符串,数字等的基本数组)没有嵌套数组
function diffArrays(arr1, arr2, returnUnion){
var ret = [];
var test = {};
var bigArray, smallArray, key;
if(arr1.length >= arr2.length){
bigArray = arr1;
smallArray = arr2;
} else {
bigArray = arr2;
smallArray = arr1;
}
for(var i=0;i<bigArray.length;i++){
key = bigArray[i];
test[key] = true;
}
if(!returnUnion){
//diffing
for(var i=0;i<smallArray.length;i++){
key = smallArray[i];
if(!test[key]){
test[key] = null;
}
}
} else {
//union
for(var i=0;i<smallArray.length;i++){
key = smallArray[i];
if(!test[key]){
test[key] = true;
}
}
}
for(var i in test){
ret.push(i);
}
return ret;
}
array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]
diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]
注意排序可能不会像上面提到的那样…但是如果需要的话,可以在数组上调用.sort()对其进行排序。
下面是另一个可以返回差异的解决方案,就像git diff一样:(它已经用typescript编写,如果你不使用typescript版本,只需删除类型)
/**
* util function to calculate the difference between two arrays (pay attention to 'from' and 'to'),
* it would return the mutations from 'from' to 'to'
* @param { T[] } from
* @param { T[] } to
* @returns { { [x in string]: boolean } } it would return the stringified version of array element, true means added,
* false means removed
*/
export function arrDiff<T>(from: T[], to: T[]): { [x in string]: boolean } {
var diff: { [x in string]: boolean } = {};
var newItems: T[] = []
diff = from.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})
for (var i = 0; i < to.length; i++) {
if (diff[JSON.stringify(to[i])]) {
delete diff[JSON.stringify(to[i])]
} else {
newItems.push(to[i])
}
}
return {
...Object.keys(diff).reduce((a, e) => ({ ...a, [e]: false }), {}),
...newItems.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})
}
}
下面是一个用法示例:
arrDiff(['a', 'b', 'c'], ['a', 'd', 'c', 'f']) //{"b": false, "d": true, "f": true}
对称和线性复杂度。需要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));
}