是否有一种方法可以在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"]
当前回答
数据:
var new_storage = JSON.parse('[{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0006"}]');
var old_storage = JSON.parse('[{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0005"}]');
使用过滤器:
var diff = new_storage
.filter(x => {if(!(old_storage.filter(y => y.id_order==x.id_order)).length){return x}})
.concat(old_storage
.filter(x => {if(!(new_storage.filter(y => y.id_order==x.id_order)).length){return x}})
)
console.log(JSON.stringify(diff))
两个数组的结果不同
[{"id_order":"0006"},{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0005"}]
其他回答
以上Joshaven Potter的回答非常棒。但是它返回数组B中不在数组C中的元素,而不是反过来。例如,如果var a=[1,2,3,4,5,6]。diff([3、4、5、7]);然后它将输出:==>[1,2,6],而不是[1,2,6,7],这是两者之间的实际差异。你仍然可以使用上面的Potter代码,但也可以简单地向后做一次比较:
Array.prototype.diff = function(a) {
return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};
////////////////////
// Examples
////////////////////
var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);
这应该输出:[1,2,6,7]
function diff(a1, a2) {
return a1.concat(a2).filter(function(val, index, arr){
return arr.indexOf(val) === arr.lastIndexOf(val);
});
}
合并这两个数组,唯一的值将只出现一次,因此indexOf()将与lastIndexOf()相同。
这是我用来获得两个数组之间的差异的函数-它适用于数值,字符串,混合num/字符串数组。在数组/多维数组中不是对象文字
function diff(arr1, arr2) {
var x,
t;
function uniq(a, b) {
t = b;
if( (b === 0 && x[b+1]!==a) ||
(t > 0 && a !== x[b+1] && a !== x[b-1]) ) {
return a;
}
}
x = arr1.concat(arr2).sort();
return x.filter(uniq);
}
var a1 = ['a', 'b', 'e', 'c'],
a2 = ['b', 'a', 'c', 'f' ];
diff(a1, a2);
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) );
我想这个例子是一个很好的起点,可以让你了解函数式编程的含义:
使用可以以许多不同方式组合在一起的构建块进行编程。
随着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"]。