# 如何获得两个数组之间的差异？

``var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; // need ["c", "d"]` `

` `function arr_diff (a1, a2) { var a = [], diff = []; for (var i = 0; i < a1.length; i++) { a[a1[i]] = true; } for (var i = 0; i < a2.length; i++) { if (a[a2[i]]) { delete a[a2[i]]; } else { a[a2[i]] = true; } } for (var k in a) { diff.push(k); } return diff; };` `

` `Array.prototype.diff = function(a) { return this.filter(function(i) {return a.indexOf(i) < 0;}); }; //////////////////// // Examples //////////////////// [1,2,3,4,5,6].diff( [3,4,5] ); // => [1, 2, 6] ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]); // => ["test5", "test6"]` `

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

`diff`现在包含`old_array`中不在`new_array`

` `let difference = arr1.filter(x => arr2.indexOf(x) == -1);` `

` `let difference = arr1 .filter(x => arr2.indexOf(x) == -1) .concat(arr2.filter(x => arr1.indexOf(x) == -1));` `

` `(R)eturns the values from array that are not present in the other arrays _.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4]` `

` `_([1, 2, 3, 4, 5]).difference([5, 2, 10]);` `

## 普通的JavaScript

` `var a1 = ['a', 'b' ]; var a2 = [ 'b', 'c'];` `
1. 如果你想得到`['a']` ，使用这个函数：

` `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; }` `
2. 如果你想得到`['a', 'c']` （包含在`a1``a2`所有元素，但不是两个 – 所谓的对称差异 ），使用这个函数：

` `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; }` `

## ES6 Set，用于非常大的数组

` `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)); }` `

## 笔记

` `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}` `

` `var a1 = ['1','2','3','4','6']; var a2 = ['3','4','5']; var items = new Array(); items = jQuery.grep(a1,function (item) { return jQuery.inArray(item, a2) < 0; });` `

` `var array1 = ["test1", "test2","test3", "test4"]; var array2 = ["test1", "test2","test3","test4", "test5", "test6"]; var _array = new Array(); _array = jQuery.grep(array2, function (item) { return jQuery.inArray(item, array1) < 0; });` `
` `function diff(a1, a2) { return a1.concat(a2).filter(function(val, index, arr){ return arr.indexOf(val) === arr.lastIndexOf(val); }); }` `

` `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']` `

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);` `

` `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)))];` `

## function方法与ES2015

` `[+left difference] [-intersection] [-right difference] [-left difference] [-intersection] [+right difference] [+left difference] [-intersection] [+right difference]` `

### 左派`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) );` `

` `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]` `
` `Array.prototype.difference = function(e) { return this.filter(function(i) {return e.indexOf(i) < 0;}); }; eg:- [1,2,3,4,5,6,7].difference( [3,4,5] ); => [1, 2, 6 , 7]` `

` `var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; function diffArray(arr1, arr2) { var newArr = []; var myArr = arr1.concat(arr2); newArr = myArr.filter(function(item){ return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0; }); alert(newArr); } diffArray(a1, a2);` `
` `var array1 = ["test1", "test2","test3", "test4"]; var array2 = ["test1", "test2","test3","test4", "test5", "test6"]; var array3 = array2.subtract( array1 ); // ["test5", "test6"] var array4 = array1.exclusion( array2 ); // ["test5", "test6"]` `

` `Array.prototype.contains = function(needle){ for (var i=0; i<this.length; i++) if (this[i] == needle) return true; return false; } Array.prototype.diff = function(compare) { return this.filter(function(elem) {return !compare.contains(elem);}) } var a = new Array(1,4,7, 9); var b = new Array(4, 8, 7); alert(a.diff(b));` `

` `function diff(arr1, arr2) { var newArr = []; var arr = arr1.concat(arr2); for (var i in arr){ var f = arr[i]; var t = 0; for (j=0; j<arr.length; j++){ if(arr[j] === f){ t++; } } if (t === 1){ newArr.push(f); } } return newArr; }` `
` `function diffArray(arr1, arr2) { var newArr = arr1.concat(arr2); return newArr.filter(function(i){ return newArr.indexOf(i) == newArr.lastIndexOf(i); }); }` `

` `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"]` `

littlebit修复最好的答案

` `function arr_diff(a1, a2) { var a=[], diff=[]; for(var i=0;i<a1.length;i++) a[a1[i]]=a1[i]; for(var i=0;i<a2.length;i++) if(a[a2[i]]) delete a[a2[i]]; else a[a2[i]]=a2[i]; for(var k in a) diff.push(a[k]); return diff; }` `

• 纯JavaScript解决scheme（无库）
• 与旧版浏览器兼容（不使用`filter`
• 为O（n ^ 2）
• 可选的`fn`callback参数，可以指定如何比较数组项目
` `function diff(a, b, fn){ var max = Math.max(a.length, b.length); d = []; fn = typeof fn === 'function' ? fn : false for(var i=0; i < max; i++){ var ac = i < a.length ? a[i] : undefined bc = i < b.length ? b[i] : undefined; for(var k=0; k < max; k++){ ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac; bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc; if(ac == undefined && bc == undefined) break; } ac !== undefined && d.push(ac); bc !== undefined && d.push(bc); } return d; } alert( "Test 1: " + diff( [1, 2, 3, 4], [1, 4, 5, 6, 7] ).join(', ') + "\nTest 2: " + diff( [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}], [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}], function(a, b){ return a.id == b.id; } ).join(', ') );` `
` `function diff(arr1, arr2) { var filteredArr1 = arr1.filter(function(ele) { return arr2.indexOf(ele) == -1; }); var filteredArr2 = arr2.filter(function(ele) { return arr1.indexOf(ele) == -1; }); return filteredArr1.concat(filteredArr2); } diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]` `

` `function diff(o, n) { // deal with empty lists if (o == undefined) o = []; if (n == undefined) n = []; // sort both arrays (or this won't work) o.sort(); n.sort(); // don't compare if either list is empty if (o.length == 0 || n.length == 0) return {added: n, removed: o}; // declare temporary variables var op = 0; var np = 0; var a = []; var r = []; // compare arrays and add to add or remove lists while (op < o.length && np < n.length) { if (o[op] < n[np]) { // push to diff? r.push(o[op]); op++; } else if (o[op] > n[np]) { // push to diff? a.push(n[np]); np++; } else { op++;np++; } } // add remaining items if( np < n.length ) a = a.concat(n.slice(np, n.length)); if( op < o.length ) r = r.concat(o.slice(op, o.length)); return {added: a, removed: r}; }` `

` ` function find_diff(arr1, arr2) { diff = []; joined = arr1.concat(arr2); for( i = 0; i <= joined.length; i++ ) { current = joined[i]; if( joined.indexOf(current) == joined.lastIndexOf(current) ) { diff.push(current); } } return diff; }` `

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

NB：我们正在修改Array03而不是Array01，以免搞乱气泡sorting的嵌套循环！

` `_.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4] _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]` `

` `[1,2,3].diff([1,2]); //Return ["3", "remove", "diff"] This is the wrong version` `

` `Array.prototype.diff = function(array2) { var a = [], diff = [], array1 = this || []; for (var i = 0; i < array1.length; i++) { a[array1[i]] = true; } for (var i = 0; i < array2.length; i++) { if (a[array2[i]]) { delete a[array2[i]]; } else { a[array2[i]] = true; } } for (var k in a) { if (!a.hasOwnProperty(k)){ continue; } diff.push(k); } return diff; }` `

` `if (!Array.prototype.diff) { Array.prototype.diff = function (a) { return \$.grep(this, function (i) { return \$.inArray(i, a) === -1; }); }; }` `