是否有一种方法可以在JavaScript中返回两个数组之间的差异?

例如:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

当前回答

转换为字符串对象类型:

[1, 1].toString() === [1, 1].toString(); // true

其他回答

下面是一个稍微修改的版本,它使用Object来存储哈希,可以处理数组中的数字和字符串。

function arrDiff(a, b) {
  const hash = {};
  a.forEach(n => { hash[n] = n; });
  b.forEach(n => {
    if (hash[n]) {
      delete hash[n];
    } else {
      hash[n] = n;
    }
  });
  return Object.values(hash);
}

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 arrayDiff(a, b) {
      return a.concat(b).filter(val => !(b.includes(val)));
      //(or) return a.concat(b).filter(val => !(a.includes(val) && b.includes(val)));
    }

困难的方法(如果你想做一些比.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;
    });
}

另一种解决问题的方法

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]