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

例如:

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

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

当前回答

如果你的数组包含对象,如果你想比较一个属性,就会变得有点困难。

幸运的是,lodash使用_contains和_.pluck使这非常简单:

var list1 = [{id: 1},{id: 2}];
var list1 = [{id: 1},{id: 2}, {id: 3}];

//es6
var results = list2.filter(item => {
  return !_.contains(_.pluck(list1, 'id'), item.id);
});

//es5
var results = list2.filter(function(item){
  return !_.contains(_.pluck(list1, 'id'), item.id);
});

//results contains [{id: 3}]

其他回答

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

const diffArr = a1.filter(o => !a2.includes(o));

console.log(diffArr);

输出:

[ 'a', 'b' ]

纯JavaScript

对于“差异”有两种可能的解释。我让你选你想要的。假设你有:

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

If you want to get ['a'], use this function: function difference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } return result; } If you want to get ['a', 'c'] (all elements contained in either a1 or a2, but not both -- the so-called symmetric difference), use this function: function symmetricDifference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } for (i = 0; i < a2.length; i++) { if (a1.indexOf(a2[i]) === -1) { result.push(a2[i]); } } return result; }

斜线/下划线

如果你正在使用lodash,你可以使用_。差异(a1, a2)(上述情况1)或_。Xor (a1, a2)(情形2)

如果你使用的是Underscore.js,你可以使用_。情况1的差分(a1, a2)函数。

ES6 Set,用于非常大的数组

上面的代码适用于所有浏览器。然而,对于超过10,000个项目的大型数组,它变得相当慢,因为它有O(n²)的复杂度。在许多现代浏览器中,我们可以利用ES6 Set对象来加快速度。Lodash在可用时自动使用Set。如果你不使用lodash,使用下面的实现,灵感来自Axel Rauschmayer的博客文章:

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

笔记

如果您关心-0、+0、NaN或稀疏数组,那么所有示例的行为都可能令人惊讶或不明显。(对于大多数用途来说,这并不重要。)

function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

合并这两个数组,唯一的值将只出现一次,因此indexOf()将与lastIndexOf()相同。

function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  return newArr.filter(function(i){
    return newArr.indexOf(i) == newArr.lastIndexOf(i);
  });
}

这对我很有用

简单地比较所有值,并返回数组与不重复的值。

var main = [9, '$', 'x', 'r', 3, 'A', '#', 0, 1];

var arr0 = ['Z', 9, 'e', '$', 'r'];
var arr1 = ['x', 'r', 3, 'A', '#'];
var arr2 = ['m', '#', 'a', 0, 'r'];
var arr3 = ['$', 1, 'n', '!', 'A'];


Array.prototype.diff = function(arrays) {
    var items = [].concat.apply(this, arguments);
    var diff = [].slice.call(items), i, l, x, pos;

    // go through all items
    for (x = 0, i = 0, l = items.length; i < l; x = 0, i++) {
        // find all positions
        while ((pos = diff.indexOf(items[i])) > -1) {
            // remove item + increase found count
            diff.splice(pos, 1) && x++;
        }
        // if item was found just once, put it back
        if (x === 1) diff.push(items[i]);
    }
    // get all not duplicated items
    return diff;
};

main.diff(arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"

[].diff(main, arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"