是否有一种方法可以在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的到来,带有sets和splat操作符(当时只在Firefox中工作,请检查兼容性表),你可以编写以下一行代码:
var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set(a.filter(x => !b1.has(x)))];
结果是["c", "d"]。
其他回答
我一直在寻找一个不涉及使用不同库的简单答案,我想出了我自己的答案,我想这里没有提到过。 我不知道它的效率如何,但它确实有效;
function find_diff(arr1, arr2) {
diff = [];
joined = arr1.concat(arr2);
for( i = 0; i <= joined.length; i++ ) {
current = joined[i];
if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
diff.push(current);
}
}
return diff;
}
对于我的代码,我也需要删除副本,但我想这并不总是可取的。
我想主要的缺点是它可能会比较许多已经被拒绝的选择。
另一种解决问题的方法
function diffArray(arr1, arr2) {
return arr1.concat(arr2).filter(function (val) {
if (!(arr1.includes(val) && arr2.includes(val)))
return val;
});
}
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
同样,你可以使用箭头函数语法:
const diffArray = (arr1, arr2) => arr1.concat(arr2)
.filter(val => !(arr1.includes(val) && arr2.includes(val)));
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
对称和线性复杂度。需要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));
}
ES2015的函数方法
计算两个数组之间的差值是Set操作之一。这个术语已经表明应该使用本机Set类型,以便提高查找速度。不管怎样,当你计算两个集合之间的差值时,有三种排列:
[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]
下面是反映这些排列的功能性解决方案。
离开的区别:
// small, reusable auxiliary functions const apply = f => x => f(x); const flip = f => y => x => f(x) (y); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // left difference const differencel = xs => ys => { const zs = createSet(ys); return filter(x => zs.has(x) ? false : true ) (xs); }; // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,3,6,7,8,9]; // run the computation console.log( differencel(xs) (ys) );
正确的区别:
差异是微不足道的。这与翻转的参数不同。为了方便,你可以写一个函数:const differencer = flip(difference)。这是所有!
对称的区别:
现在我们有了左边和右边,实现对称的差异也变得微不足道:
// small, reusable auxiliary functions const apply = f => x => f(x); const flip = f => y => x => f(x) (y); const concat = y => xs => xs.concat(y); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // left difference const differencel = xs => ys => { const zs = createSet(ys); return filter(x => zs.has(x) ? false : true ) (xs); }; // symmetric difference const difference = ys => xs => concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys)); // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,3,6,7,8,9]; // run the computation console.log( difference(xs) (ys) );
我想这个例子是一个很好的起点,可以让你了解函数式编程的含义:
使用可以以许多不同方式组合在一起的构建块进行编程。
function array_diff(array1, array2) {
let returnArray = [];
$.each(array1, function(index, value) {
let findStatus = false;
if (Array.isArray(array2)) {
$.each(array2, function(index2, value2) {
if (value == value2) findStatus = true;
});
} else {
if (value == array2) {
findStatus = true;
}
}
if (findStatus == false) {
returnArray.push(value);
}
});
return returnArray;
}