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

例如:

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

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

当前回答

还有另一个答案,但似乎没有人提到jsperf,他们比较了几种算法和技术支持:https://jsperf.com/array-difference-javascript似乎使用过滤器得到了最好的结果。谢谢

其他回答

类似于Ian Grainger的解决方案(但在打字稿中):

function findDiffs(arrayOne: string[], arrayTwo: string[]) {

    let onlyInArrayOne = []
    let onlyInArrayTwo = []
    let share = []
    let [arrayOneCopy, arrayTwoCopy] = [[...arrayOne], [...arrayTwo]]

    arrayOneCopy.sort(); arrayTwoCopy.sort()

    while (arrayOneCopy.length !== 0 && arrayTwoCopy.length !== 0) {
        if (arrayOneCopy[0] == arrayTwoCopy[0]) {
            share.push(arrayOneCopy[0])
            arrayOneCopy.splice(0, 1)
            arrayTwoCopy.splice(0, 1)
        }
        if (arrayOneCopy[0] < arrayTwoCopy[0]) {
            onlyInArrayOne.push(arrayOneCopy[0])
            arrayOneCopy.splice(0, 1)
        }
        if (arrayOneCopy[0] > arrayTwoCopy[0]) {
            onlyInArrayTwo.push(arrayTwoCopy[0])
            arrayTwoCopy.splice(0, 1)
        }
    }
    onlyInArrayTwo = onlyInArrayTwo.concat(arrayTwoCopy)
    onlyInArrayOne = onlyInArrayOne.concat(arrayOneCopy)

    return {
        onlyInArrayOne,
        onlyInArrayTwo,
        share,
        diff: onlyInArrayOne.concat(onlyInArrayTwo)
    }
}

// arrayOne: [ 'a', 'b', 'c', 'm', 'y' ] 
// arrayTwo: [ 'c', 'b', 'f', 'h' ]
//
// Results: 
// { 
//    onlyInArrayOne: [ 'a', 'm', 'y' ],
//    onlyInArrayTwo: [ 'f', 'h' ],
//    share: [ 'b', 'c' ],
//    diff: [ 'a', 'm', 'y', 'f', 'h' ] 
// }

转换为字符串对象类型:

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

对于想要从一个数组中减去另一个数组的人的回应…

如果不超过1000个元素试试这个…

设置一个新变量来复制Array01,并将其命名为Array03。

现在,使用冒泡排序算法比较Array01和Array02的元素,并在找到匹配时进行比较 对Array03执行以下操作…

 if (Array01[x]==Array02[y]) {Array03.splice(x,1);}

注意:我们正在修改Array03而不是Array01,这样就不会搞砸冒泡排序的嵌套循环!

最后,用一个简单的赋值操作将Array03的内容复制到Array01,就完成了。

使用indexOf()的解决方案对于小型数组是可以的,但是随着长度的增长,算法的性能将接近O(n^2)。这里有一个解决方案,将执行非常大的数组使用对象作为关联数组存储数组项作为键;它还自动消除重复项,但只适用于字符串值(或可以安全地存储为字符串的值):

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']

只是想…为了一个挑战;-)这个工作…(对于字符串,数字等的基本数组)没有嵌套数组

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

注意排序可能不会像上面提到的那样…但是如果需要的话,可以在数组上调用.sort()对其进行排序。