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

例如:

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

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

当前回答

ES6中一个更简洁的方法是以下解决方案。

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

区别

a2.filter(d => !a1.includes(d)) // gives ["c", "d"]

十字路口

a2.filter(d => a1.includes(d)) // gives ["a", "b"]

析取联合(对称差分)

[ ...a2.filter(d => !a1.includes(d)),
  ...a1.filter(d => !a2.includes(d)) ]

其他回答

基于思考者的答案,但允许重复。

映射在映射值出现时增加它们,如果它们在另一个数组中,则减少它们。

任何剩余的部分都将包括在差额中。

function diff(curr, prev) { let a = curr.split('').sort(), b = prev.split('').sort(), c = arrDiff(a, b); console.log(JSON.stringify(a), '-', JSON.stringify(b), '=', JSON.stringify(c)); return c; } function arrDiff(larger, smaller) { var entries = {}; for (var i = 0; i < larger.length; i++) { entries[larger[i]] = (entries[larger[i]] || 0) + 1; } for (var i = 0; i < smaller.length; i++) { if (entries[smaller[i]]) { entries[smaller[i]] -= 1; } else { entries[smaller[i]] = (entries[smaller[i]] || 0) + 1; } } return Object.keys(entries).sort().reduce((diff, key) => { if (entries[key] > 0) { for (var i = 0; i < entries[key]; i++) { diff.push(key); } } return diff; }, []); } // Smaller is a subset of Larger console.log('Result:', JSON.stringify(diff('ENLIGHTEN', 'LENGTHEN'))); // [ I ] console.log('Result:', JSON.stringify(diff('STRENGTH', 'TENTHS'))); // [ G, R ] // Both have a unique value console.log('Result:', JSON.stringify(diff('BUBBLE', 'RUBBLE'))); // [ B, R ] .as-console-wrapper { top: 0; max-height: 100% !important; }

这是受到了思想者接受的答案的启发,但是思想者的答案似乎假设数组是集合。如果数组是["1","2"]和["1","1","2","2"],它就不成立了

这些数组之间的差值是["1","2"]。下面的解决方案是O(n*n),所以不理想,但如果您有大数组,它也比思想者的解决方案具有内存优势。

如果你首先处理的是集合,思想者的解决方案肯定更好。如果你有一个可以访问过滤器的Javascript新版本,你也应该使用它们。这只适用于那些不处理集的人,并且正在使用旧版本的JavaScript(无论出于什么原因)…

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   

这是目前为止最简单的方法来得到你正在寻找的结果,使用jQuery:

var diff = $(old_array).not(new_array).get();

Diff现在包含了old_array中不在new_array中的内容

在这种情况下,您可以使用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}

这个问题很老了,但仍然是javascript数组减法的热门问题,所以我想添加我正在使用的解决方案。适用于以下情况:

var a1 = [1,2,2,3]
var a2 = [1,2]
//result = [2,3]

下面的方法将产生预期的结果:

function arrayDifference(minuend, subtrahend) {
  for (var i = 0; i < minuend.length; i++) {
    var j = subtrahend.indexOf(minuend[i])
    if (j != -1) {
      minuend.splice(i, 1);
      subtrahend.splice(j, 1);
    }
  }
  return minuend;
}

需要注意的是,该函数不包括减数中没有被减数的值:

var a1 = [1,2,3]
var a2 = [2,3,4]
//result = [1]