如何在JavaScript中获得两个数组之间的差异?

有没有办法返回JavaScript中两个数组之间的差异?

例如:

var a1 = ['a', 'b'];var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
1025398 次浏览

在这种情况下,您可以使用设置。它针对此类操作(联合、交集、差异)进行了优化。

确保它适用于您的情况,一旦它不允许重复。

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}

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

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){//diffingfor(var i=0;i<smallArray.length;i++){key = smallArray[i];if(!test[key]){test[key] = null;}}} else {//unionfor(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"]

请注意,排序可能不会如上所述……但如果需要,请在数组上调用. sor()对其进行排序。

这个答案是在2009年写的,所以它有点过时了,对于理解这个问题也很有教育意义。我今天使用的最佳解决方案是

let difference = arr1.filter(x => !arr2.includes(x));

(其他作者在这里)

我假设您正在比较一个普通数组。如果不是,您需要将进行循环更改为为…在循环。

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;}
console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));console.log(arr_diff("abcd", "abcde"));console.log(arr_diff("zxc", "zxc"));

这个怎么样:

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

所以这样你就可以做array1.diff(array2)来获得它们的差异(算法的时间复杂度很糟糕-O(array1.lengthxarray2.length)我相信)

我想要一个类似的函数,它接收一个旧数组和一个新数组,并给我一个添加项数组和一个删除项数组,我希望它是有效的(所以没有.包含!)。

你可以在这里玩我提出的解决方案:http://jsbin.com/osewu3/12

任何人都可以看到该算法的任何问题/改进?谢谢!

代码列表:

function diff(o, n) {// deal with empty listsif (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 emptyif (o.length == 0 || n.length == 0) return {added: n, removed: o};
// declare temporary variablesvar op = 0; var np = 0;var a = []; var r = [];
// compare arrays and add to add or remove listswhile (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 itemsif( 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};}

Array.prototype.diff = function(a) {return this.filter(function(i) {return a.indexOf(i) < 0;});};
//////////////// Examples ////////////////
const dif1 = [1,2,3,4,5,6].diff( [3,4,5] );console.log(dif1); // => [1, 2, 6]

const dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);console.log(dif2); // => ["test5", "test6"]

说明.indexOf().filter()在IE9之前不可用。

使用http://phrogz.net/JS/ArraySetMath.js,您可以:

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

我一直在寻找一个不涉及使用不同库的简单答案,我想到了我自己的,我认为这里没有提到。我不知道它有多有效,但它有效;

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

对于我的代码,我也需要取出重复项,但我想这并不总是首选。

我想主要的缺点是它可能会比较许多已经被拒绝的选择。

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

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

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

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

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

注意:我们正在修改Array03而不是Array01,以免搞砸气泡排序的嵌套循环!

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

Samuel:“对于我的代码,我也需要取出重复项,但我想这并不总是首选。“我想主要的缺点是它可能会比较许多已经被拒绝的选项。

当比较两个列表、数组等,且元素小于1000时,行业标准中的3GL世界是使用气泡排序,避免了欺骗。

代码看起来像这样……(未经测试,但应该可以工作)

var Array01=new Array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P');var Array02=new Array('X','B','F','W','Z','X','J','P','P','O','E','N','Q');var Array03=Array01;
for(x=1; x<Array02.length; x++) {for(y=0; y<Array01.length-1; y++) {if (Array01[y]==Array02[x]) {Array03.splice(y,1);}}}
Array01=Array03;

为了测试输出…

for(y=0; y<Array01.length; y++) {document.write(Array01[y])}

要从另一个数组中减去一个数组,只需使用下面的代码片段:

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

它将返回['1,'2','6'],它们是第一个数组中不存在于第二个数组中的项。

因此,根据您的问题示例,以下代码是确切的解决方案:

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

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

这将考虑当前元素的类型。b/c当我们创建[a1[i]]时,它会将其原始值转换为字符串,因此我们丢失了实际值。

我在这里阅读的答案有很多问题,使它们在实际编程应用中的价值有限。

首先,你需要有一种方法来控制数组中的两个元素“相等”意味着什么。如果你想弄清楚是否根据ID或类似的东西更新对象数组,===比较不会削减它,坦率地说,这可能是你需要diff函数的最有可能的情况之一。它还限制了你可以与===运算符进行比较的事物数组,即字符串、整数等,这对成年人来说几乎是不可接受的。

其次,diff操作有三种状态结果:

  1. 在第一个数组中但不在第二个数组中的元素
  2. 两个数组共有的元素
  3. 在第二个数组中但不在第一个数组中的元素

我认为这意味着你需要不少于2个循环,但如果有人知道如何将其减少到一个,我就会对肮脏的技巧持开放态度。

这是我拼凑起来的东西,我想强调的是,我完全不关心它在旧版本的微轴浏览器中不起作用。如果你在像IE这样的劣质编码环境中工作,你可以修改它以在你所坚持的不令人满意的限制内工作。

Array.defaultValueComparison = function(a, b) {return (a === b);};
Array.prototype.diff = function(arr, fnCompare) {
// validate params
if (!(arr instanceof Array))arr = [arr];
fnCompare = fnCompare || Array.defaultValueComparison;
var original = this, exists, storage,result = { common: [], removed: [], inserted: [] };
original.forEach(function(existingItem) {
// Finds common elements and elements that// do not exist in the original array
exists = arr.some(function(newItem) {return fnCompare(existingItem, newItem);});
storage = (exists) ? result.common : result.removed;storage.push(existingItem);
});
arr.forEach(function(newItem) {
exists = original.some(function(existingItem) {return fnCompare(existingItem, newItem);});
if (!exists)result.inserted.push(newItem);
});
return result;
};

使用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']

下划线中的差异方法(或其直接替换,Lo-Dash)也可以这样做:

(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]

与任何Undercore函数一样,您也可以以更面向对象的风格使用它:

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

乔斯海文·波特的上述答案很棒。但它返回数组B中不在数组C中的元素,但不是相反。例如,如果var a=[1,2,3,4,5,6].diff( [3,4,5,7]);,那么它将输出: ==> [1,2,6],而是没有[1,2,6,7],这是两者之间的实际差异。你仍然可以使用上面的波特代码,但也只需向后重做一次比较:

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

这应该输出:[ 1, 2, 6, 7 ]

您可以使用underscore.js:http://underscorejs.org/#intersection

你需要数组的方法:

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

这是迄今为止使用jQuery获得您正在寻找的结果的最简单方法:

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

diff现在包含old_array中的内容,而不是new_array中的内容

如果不使用hasOwnProperty,那么我们有不正确的元素。例如:

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

我陷入了这个问题,这是为了得到两个简单数组的差异

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

我不明白为什么不使用基本的for循环:

for(var i=0; i < a1.length; i++) {for(var j=0; j < a2.length; j++) {if(a1[i] == a2[j]) {a2.splice(j, 1);}}}

这将返回所需的["c", "d"]

[编辑]在上面提出,看到晚了。

无论如何,有什么好的理由来避免这个简单的解决方案吗?

使用我目前正在使用的jQuery解决方案做出贡献:

if (!Array.prototype.diff) {Array.prototype.diff = function (a) {return $.grep(this, function (i) { return $.inArray(i, a) === -1; });};}
var result = [];var arr1 = [1,2,3,4];var arr2 = [2,3];arr1.forEach(function(el, idx) {function unEqual(element, index, array) {var a = el;return (element!=a);}if (arr2.every(unEqual)) {result.push(el);};});alert(result);

这个问题很老,但仍然是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;}

应该注意的是,该函数不包括被减数中不存在的subtrahend值:

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

这是受Thinker接受的答案的启发,但Thinker的答案似乎假设数组是集合。如果数组是[ "1", "2" ][ "1", "1", "2", "2" ],它就会分崩离析

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

如果你一开始就在处理集合,Thinker的解决方案肯定更好。如果你有一个可以访问过滤器的较新版本的JavaScript,你也应该使用这些。这只适用于那些不处理集合而是使用旧版本JavaScript的人(无论出于什么原因)…

if (!Array.prototype.diff) {Array.prototype.diff = function (array) {// if the other array is a falsy value, return a copy of this arrayif ((!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;}}

只是修剪字符串以确保……空格不会影响diff

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].trim()]) delete a[a2[i].trim()];else a[a2[i].trim()]=true;for(var k in a)diff.push(k);return diff;}

快速解决方案。虽然其他人似乎已经发布了相同方法的不同变体。我不确定这是否适合大型数组,但它适用于我的数组,它不会大于10或15。

差异b-a

for(var i = 0; i < b.length; i++){for(var j = 0; j < a.length; j ++){var loc = b.indexOf(a[j]);if(loc > -1){b.splice(loc, 1);}}}
  • 纯JavaScript解决方案(无库)
  • 与旧浏览器兼容(不使用filter
  • O(n^2)
  • 可选的fn回调参数,可让您指定如何比较数组项

function diff(a, b, fn){var max = Math.max(a.length, b.length);d = [];fn = typeof fn === 'function' ? fn : falsefor(var i=0; i < max; i++){var ac = i < a.length ? a[i] : undefinedbc = 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(', '));

我尝试了上面所有的方法,但是当你需要匹配而不接受重复时,没有一个有效。

例如:

var a1 = [1, 2, 1, 4], a2 = [1, 2, 4];

会返回一个空的diff数组,因为2会在第二个数组中找到一次,即使我们需要它匹配两次。

所以我设法解决了一些问题:

Array.prototype.diff = function(a) {return this.filter(function(item) {match = a.indexOf(item);if (match)a.splice(match, 1);return match < 0;});};

这是我用来获取2个数组之间差异的函数-它适用于数字、字符串、混合num/string数组。不是数组/多维数组中的对象文字

function diff(arr1, arr2) {
var x,t;
function uniq(a, b) {t = b;
if( (b === 0 && x[b+1]!==a) ||(t > 0 && a !== x[b+1] && a !== x[b-1]) ) {return  a;}}

x = arr1.concat(arr2).sort();
return x.filter(uniq);}
var a1 = ['a', 'b', 'e', 'c'],a2 = ['b', 'a', 'c', 'f' ];
diff(a1, a2);

随着带有集合和spat运算符的ES6的到来(在仅在Firefox中工作时,检查兼容性表),您可以编写以下一个行:

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

这将导致[ "c", "d" ]

CoffeeScript版本:

diff = (val for val in array1 when val not in array2)

纯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. 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 / Underscore

If you are using lodash, you can use _.difference(a1, a2) (case 1 above) or _.xor(a1, a2) (case 2).

If you are using Underscore.js, you can use the _.difference(a1, a2) function for case 1.

ES6 Set, for very large arrays

The code above works on all browsers. However, for large arrays of more than about 10,000 items, it becomes quite slow, because it has O(n²) complexity. On many modern browsers, we can take advantage of the ES6 Set object to speed things up. Lodash automatically uses Set when it's available. If you are not using lodash, use the following implementation, inspired by Axel Rauschmayer's blog post:

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或稀疏数组,所有示例的行为可能会令人惊讶或不明显。(对于大多数用途,这并不重要。)

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

幸运的是,lodash使用_contains_.pluck很容易做到这一点:

var list1 = [{id: 1},{id: 2}];var list1 = [{id: 1},{id: 2}, {id: 3}];
//es6var results = list2.filter(item => {return !_.contains(_.pluck(list1, 'id'), item.id);});
//es5var results = list2.filter(function(item){return !_.contains(_.pluck(list1, 'id'), item.id);});
//results contains [{id: 3}]
function diff(a1, a2) {return a1.concat(a2).filter(function(val, index, arr){return arr.indexOf(val) === arr.lastIndexOf(val);});}

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

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]

这是有效的:基本上合并两个数组,寻找重复项并将不重复的内容推送到一个新的数组中,这就是区别。

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

转换为字符串对象类型:

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

使用ES7有一个更好的方法:


交叉路口

 let intersection = arr1.filter(x => arr2.includes(x));

交叉点差维恩图

对于[1,2,3] [2,3],它将产生[2,3]。另一方面,对于[1,2,3] [2,3,5]将返回同样的事情。


差异

let difference = arr1.filter(x => !arr2.includes(x));

右差维恩图

对于[1,2,3] [2,3],它将产生[1]。另一方面,对于[1,2,3] [2,3,5]将返回同样的事情。


对于对称差分,你可以这样做:

let difference = arr1.filter(x => !arr2.includes(x)).concat(arr2.filter(x => !arr1.includes(x)));

对称差分维恩图

这样,您将获得一个包含arr1中不在arr2中的所有元素的数组,反之亦然

正如@乔斯海文·波特在他的回答中指出的那样,你可以把它添加到Array.prototype这样它就可以这样使用:

Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); }[1, 2, 3].diff([2, 3])

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

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 itemsfor (x = 0, i = 0, l = items.length; i < l; x = 0, i++) {// find all positionswhile ((pos = diff.indexOf(items[i])) > -1) {// remove item + increase found countdiff.splice(pos, 1) && x++;}// if item was found just once, put it backif (x === 1) diff.push(items[i]);}// get all not duplicated itemsreturn diff;};
main.diff(arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"
[].diff(main, arr0, arr1, arr2, arr3).join(''); // returns "Zeman!"

以下是我使用的:

var newArr = a1.filter(function(elem) {return a2.indexOf(elem) === -1;}).concat( a2.filter(function(elem) {return a1.indexOf(elem) === -1;}));console.log(newArr);

或者是这个

var newArr = a1.concat(a2);function check(item) {if (a1.indexOf(item) === -1 || a2.indexOf(item) === -1) {return item;}}return newArr.filter(check);
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 diffArray(arr1, arr2) {var newArr = arr1.concat(arr2);return newArr.filter(function(i){return newArr.indexOf(i) == newArr.lastIndexOf(i);});}

这对我很管用

var arrayDifference = function(arr1, arr2){if(arr1 && arr1.length){if(arr2 && arr2.length > 0){for (var i=0, itemIndex; i<arr2.length; i++){itemIndex = arr1.indexOf(arr2[i]);if(itemIndex !== -1){arr1.splice(itemIndex, 1);}}}return arr1;}return [];};
arrayDifference([1,2,3,4,5], [1,5,6]);

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

ES2015的功能方法

在两个数组之间计算differenceSet操作之一。该术语已经表明应该使用本机Set类型,以提高查找速度。无论如何,当您计算两个集合之间的差异时,有三种排列:

[+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) );

difference

differencer很简单。它只是differencel带有翻转参数。为了方便起见,您可以编写一个函数:const differencer = flip(differencel)。仅此而已!

对称difference

现在我们有了左右两个,实现对称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) );

我想这个例子是一个很好的起点,可以让你了解函数式编程的含义:

使用可以以许多不同方式插入在一起的构建块进行编程。

数据说明:

var new_storage = JSON.parse('[{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0006"}]');
var old_storage = JSON.parse('[{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0003"},{"id_order":"0004"},{"id_order":"0005"}]');

使用过滤器:

var diff = new_storage.filter(x => {if(!(old_storage.filter(y => y.id_order==x.id_order)).length){return x}}).concat(old_storage.filter(x => {if(!(new_storage.filter(y => y.id_order==x.id_order)).length){return x}}))
console.log(JSON.stringify(diff))

两个数组的结果差异

[{"id_order":"0006"},{"id_order":"0001"},{"id_order":"0002"},{"id_order":"0005"}]

另一种解决问题的方法

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]
const difference = function (baseArray, arrayToCampare, callback = (a, b) => a!== b) {if (!(arrayToCampare instanceof Array)) {return baseArray;}return baseArray.filter(baseEl =>arrayToCampare.every(compareEl => callback(baseEl, compareEl)));}

使用JavaScript的过滤器功能的非常简单的解决方案:

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

function array_diff(a, b) {
let array = [];for(let i = 0; i <a.length; i++) {let k = 0;for( let j = 0; j < b.length; j++) {if(a[i]!==b[j]) {k++;}if(k===b.length) {array = array.concat(a[i]);}}
if(b.length ===0) {array = array.concat(a[i]);}}return array;}

//解决方案

function diff(a, b) {var u = a.slice(); //dup the arrayb.map(e => {if (u.indexOf(e) > -1) delete u[u.indexOf(e)]else u.push(e)   //add non existing item to temp array})return u.filter((x) => {return (x != null)}) //flatten result}

这是我如何得到两个数组的区别。纯粹和干净。

它将返回一个包含[添加列表]和[删除列表]的对象。

  function getDiff(past, now) {let ret = { add: [], remove: [] };for (var i = 0; i < now.length; i++) {if (past.indexOf(now[i]) < 0)ret['add'].push(now[i]);}for (var i = 0; i < past.length; i++) {if (now.indexOf(past[i]) < 0)ret['remove'].push(past[i]);}return ret;}

如果数组不是简单类型,则可以适应上述答案之一:

Array.prototype.diff = function(a) {return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});};

此方法适用于复杂对象的数组。

您可以使用一个公共对象并计算第一个数组中每个值的频率。对于第二个数组,递减公共对象中的值。然后遍历所有键并添加所有值大于1的键。

const difference = (a1, a2) => {var obj = {};a1.forEach(v => obj[v] = (obj[v] || 0) + 1);a2.forEach(v => obj[v] = (obj[v] || 0) - 1);return Object.keys(obj).reduce((r,k) => {if(obj[k] > 0)r = r.concat(Array.from({length: obj[k]}).fill(k));return r;},[]);};const result = difference(['a', 'a', 'b', 'c', 'd'], ['a', 'b']);console.log(result);

选择的答案只有一半正确。您必须比较两种方式的数组以获得完整的答案。

const ids_exist = ['1234','5678','abcd',]
const ids_new = ['1234','5678','efjk','9999',]
function __uniq_Filter (__array_1, __array_2) {const one_not_in_two = __array_1.filter(function (obj) {return __array_2.indexOf(obj) == -1})const two_not_in_one = __array_2.filter(function (obj) {return __array_1.indexOf(obj) == -1})return one_not_in_two.concat(two_not_in_one)}
let uniq_filter = __uniq_Filter(ids_exist, ids_new)
console.log('uniq_filter', uniq_filter) // => [ 'abcd', 'efjk', '9999' ]

对称线性复杂度。需要ES6。

function arrDiff(arr1, arr2) {var arrays = [arr1, arr2].sort((a, b) => a.length - b.length);var smallSet = new Set(arrays[0]);
return arrays[1].filter(x => !smallSet.has(x));}

**这将根据'type'参数为任何2个数组返回一个唯一值数组,或一个重复数组,或一个非重复数组(差异)。**

let json1 = ['one', 'two']let json2 = ['one', 'two', 'three', 'four']
function uniq_n_shit (arr1, arr2, type) {
let concat = arr1.concat(arr2)let set = [...new Set(concat)]
if (!type || type === 'uniq' || type === 'unique') {
return set
} else if (type === 'duplicate') {
concat = arr1.concat(arr2)return concat.filter(function (obj, index, self) {return index !== self.indexOf(obj)})
} else if (type === 'not_duplicate') {
let duplicates = concat.filter(function (obj, index, self) {return index !== self.indexOf(obj)})
for (let r = 0; r < duplicates.length; r++) {let i = set.indexOf(duplicates[r]);if(i !== -1) {set.splice(i, 1);}}
return set
}}
console.log(uniq_n_shit(json1, json2, null)) // => [ 'one', 'two', 'three', 'four' ]console.log(uniq_n_shit(json1, json2, 'uniq')) // => [ 'one', 'two', 'three', 'four' ]console.log(uniq_n_shit(json1, json2, 'duplicate')) // => [ 'one', 'two' ]console.log(uniq_n_shit(json1, json2, 'not_duplicate')) // => [ 'three', 'four' ]

要获得对称差分,您需要以两种方式比较数组(或者在多个数组的情况下以所有方式)

在此处输入图片描述


ES7(ECMAScript 2016)

// diff between just two arrays:function arrayDiff(a, b) {return [...a.filter(x => !b.includes(x)),...b.filter(x => !a.includes(x))];}
// diff between multiple arrays:function arrayDiff(...arrays) {return [].concat(...arrays.map( (arr, i) => {const others = arrays.slice(0);others.splice(i, 1);const unique = [...new Set([].concat(...others))];return arr.filter(x => !unique.includes(x));}));}

ES6(ECMAScript 2015)

// diff between just two arrays:function arrayDiff(a, b) {return [...a.filter(x => b.indexOf(x) === -1),...b.filter(x => a.indexOf(x) === -1)];}
// diff between multiple arrays:function arrayDiff(...arrays) {return [].concat(...arrays.map( (arr, i) => {const others = arrays.slice(0);others.splice(i, 1);const unique = [...new Set([].concat(...others))];return arr.filter(x => unique.indexOf(x) === -1);}));}

ES5(ECMAScript 5.1)

// diff between just two arrays:function arrayDiff(a, b) {var arrays = Array.prototype.slice.call(arguments);var diff = [];
arrays.forEach(function(arr, i) {var other = i === 1 ? a : b;arr.forEach(function(x) {if (other.indexOf(x) === -1) {diff.push(x);}});})
return diff;}
// diff between multiple arrays:function arrayDiff() {var arrays = Array.prototype.slice.call(arguments);var diff = [];
arrays.forEach(function(arr, i) {var others = arrays.slice(0);others.splice(i, 1);var otherValues = Array.prototype.concat.apply([], others);var unique = otherValues.filter(function (x, j) {return otherValues.indexOf(x) === j;});diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));});return diff;}

示例:

// diff between two arrays:const a = ['a', 'd', 'e'];const b = ['a', 'b', 'c', 'd'];arrayDiff(a, b); // (3) ["e", "b", "c"]
// diff between multiple arraysconst a = ['b', 'c', 'd', 'e', 'g'];const b = ['a', 'b'];const c = ['a', 'e', 'f'];arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]

对象数组之间的区别

function arrayDiffByKey(key, ...arrays) {return [].concat(...arrays.map( (arr, i) => {const others = arrays.slice(0);others.splice(i, 1);const unique = [...new Set([].concat(...others))];return arr.filter( x =>!unique.some(y => x[key] === y[key]));}));}

示例:

const a = [{k:1}, {k:2}, {k:3}];const b = [{k:1}, {k:4}, {k:5}, {k:6}];const c = [{k:3}, {k:5}, {k:7}];arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]

对我来说,将其作为部分函数处理感觉更容易。很惊讶没有看到函数式编程解决方案,这是我在ES6中的解决方案:

const arrayDiff = (a, b) => {return diff(b)(a);}
const contains = (needle) => (array) => {for (let i=0; i < array.length; i++) {if (array[i] == needle) return true;}
return false;}
const diff = (compare) => {return (array) => array.filter((elem) => !contains(elem)(compare))}
var a1 = ['a', 'b'];var a2 = ['a', 'b', 'c', 'd'];var diff = [];for (var i in a2) {var found = false;for (var j in a1) {if (a2[i] === a1[j]) found = true;}if (found === false) diff.push(a2[i]);}

就是这么简单。也可以与对象一起使用,检查对象的一个属性。就像

if (a2[i].id === a1[j].id) found = true;

还有另一个答案,但似乎没有人提到jspef,他们比较了几种算法和技术支持: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' ]// }

如果你不关心原始数组并且编辑它们没有问题,那么这是更快的算法:

let iterator = arrayA.values()let result = []for (entryA of iterator) {if (!arrayB.includes(entryA)) {result.push(entryA)} else {arrayB.splice(arrayB.indexOf(entryA), 1)}}
result.push(...arrayB)return result

基于思想家的回答,但允许重复。

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

剩余部分将计入差额。

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 Largerconsole.log('Result:', JSON.stringify(diff('ENLIGHTEN', 'LENGTHEN'))); // [ I ]console.log('Result:', JSON.stringify(diff('STRENGTH', 'TENTHS')));    // [ G, R ]
// Both have a unique valueconsole.log('Result:', JSON.stringify(diff('BUBBLE', 'RUBBLE')));      // [ B, R ]
.as-console-wrapper { top: 0; max-height: 100% !important; }

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

我同意@luis-sieira的解决方案

我创建了位不言而喻的功能,让初学者一步一步轻松理解:

function difference(oneArr, twoArr){var newArr = [];newArr = oneArr.filter((item)=>{return !twoArr.includes(item)});console.log(newArr)let arr = twoArr.filter((item)=>{return !oneArr.includes(item)});newArr =  newArr.concat(arr);console.log(newArr)}difference([1, 2, 3, 5], [1, 2, 3, 4, 5])

使用额外的内存来做到这一点。这样你就可以用更少的时间复杂度来解决它,O(n)而不是o(n*n)。

function getDiff(arr1,arr2){let k = {};let diff = []arr1.map(i=>{if (!k.hasOwnProperty(i)) {k[i] = 1}})arr2.map(j=>{if (!k.hasOwnProperty(j)) {k[j] = 1;} else {k[j] = 2;}})for (var i in k) {if (k[i] === 1)diff.push(+i)}return diff}getDiff([4, 3, 52, 3, 5, 67, 9, 3],[4, 5, 6, 75, 3, 334, 5, 5, 6])

根据之前的答案……取决于你是否想要一个高效或“漂亮的单线”解决方案。

一般有三种方法…

  • “手动迭代”(使用indexOf)-复杂度为O(n2)的天真(慢)

    var array_diff_naive = function(a,b){
    var i, la = a.length, lb = b.length, res = [];
    if (!la) return b; else if (!lb) return a;for (i = 0; i < la; i++) {if (b.indexOf(a[i]) === -1) res.push(a[i]);}for (i = 0; i < lb; i++) {if (a.indexOf(b[i]) === -1) res.push(b[i]);}return res;}
  • "抽象迭代"(使用过滤器和concat库方法)-手动迭代的语法糖(看起来更好,还是很烂)

    var array_diff_modern = function(a1,a2){
    
    return a1.filter(function(v) { return  !a2.includes(v); } ).concat(a2.filter(function(v) { return !a1.includes(v);}));}
  • “使用哈希表”(使用对象键)-效率更高-只有O(n),但输入数组值的范围略有限制

     var array_diff_hash = function(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;}

在jspef上看到这个
https://jsperf.com/array-diff-algo

这是一个稍微修改的版本,它使用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);}
var compare = array1.length > array2.length ? array1 : array2;var compareWith = array1.length > array2.length ? array2 : array1;var uniqueValues = compareWith.filter(function(value){if(compare.indexOf(vakye) == -1)return true;});

这将检查哪个是数组中较大的一个,然后进行比较。

function diffArray(newArr, oldArr) {var newSet = new Set(newArr)var diff = []oldArr.forEach((a) => {if(!newSet.delete(a))diff.push(a)})return diff.concat(Array.from(newSet))}
    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)));}

要查找没有重复项的2个数组中的差异

function difference(arr1, arr2){
let setA = new Set(arr1);let differenceSet = new Set(arr2.filter(ele => !setA.has(ele)));return [...differenceSet ];
}

1.difference([2,2,3,4],[2,3,3,4])将返回[]

2.difference([1,2,3],[4,5,6])将返回[4,5,6]

3.difference([1,2,3,4],[1,2])将返回[]

4.difference([1,2],[1,2,3,4])将返回[3,4]

注意:上述解决方案要求您始终将较大的数组作为第二个参数发送。要找到绝对差异,您需要首先找到两者中较大的数组,然后对其进行处理。

要查找没有重复项的2个数组中的绝对差异

function absDifference(arr1, arr2){
const {larger, smaller} = arr1.length > arr2.length ?{larger: arr1, smaller: arr2} : {larger: arr2, smaller: arr1}  
let setA = new Set(smaller);let absDifferenceSet = new Set(larger.filter(ele => !setA.has(ele)));return [...absDifferenceSet ];
}

1.absDifference([2,2,3,4],[2,3,3,4])将返回[]

2.absDifference([1,2,3],[4,5,6])将返回[4,5,6]

3.absDifference([1,2,3,4],[1,2])将返回[3,4]

4.absDifference([1,2],[1,2,3,4])将返回[3,4]

注意两个解决方案的例3

这是另一个可以返回差异的解决方案,就像git diff一样:(它是用打字稿编写的,如果你不使用打字稿版本,只需删除类型)

/*** util function to calculate the difference between two arrays (pay attention to 'from' and 'to'),* it would return the mutations from 'from' to 'to'* @param { T[] } from* @param { T[] } to* @returns { { [x in string]: boolean } } it would return the stringified version of array element, true means added,* false means removed*/export function arrDiff<T>(from: T[], to: T[]): { [x in string]: boolean } {
var diff: { [x in string]: boolean } = {};var newItems: T[] = []diff = from.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})
for (var i = 0; i < to.length; i++) {if (diff[JSON.stringify(to[i])]) {delete diff[JSON.stringify(to[i])]} else {newItems.push(to[i])}}
return {...Object.keys(diff).reduce((a, e) => ({ ...a, [e]: false }), {}),...newItems.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})}}

以下是使用示例:

arrDiff(['a', 'b', 'c'], ['a', 'd', 'c', 'f']) //{"b": false, "d": true, "f": true}

试试看。

var first = [ 1, 2, 3, 4, 5 ];var second = [ 4, 5, 6 ];     
var difference = first.filter(x => second.indexOf(x) === -1);console.log(difference);

Output: [ 1, 2, 3]

var first = [ 1, 2, 3, 4, 5 ];var second = [ 4, 5, 6 ];     
var difference = first.filter(x => second.indexOf(x) === -1);console.log(difference);

如果你想找到两个对象数组之间的差异,你可以这样做:

let arrObj = [{id: 1},{id: 2},{id: 3}]let arrObj2 = [{id: 1},{id: 3}]
let result = arrObj.filter(x => arrObj2.every(x2 => x2.id !== x.id))
console.log(result)

回复adaen关闭的帖子(比较两个包含整数的数组JavaScript):

有几个选择:

  1. 简单->您可以将第二个数组的所有条目添加到哈希图中。然后遍历第一个数组中的条目并记录哈希图中不存在的条目。
const arrOne = [2,3,10,7,9,15,7,15,21,1];const arrTwo = [3,15,1,2,21];
const hash = {};
arrTwo.forEach(a => hash[a]++);arrOne.filter(a => typeof hash[a] === 'undefined').forEach(a => console.log(a));
  1. 你的另一个选择是对两个数组进行排序。然后遍历第二个数组。在它内部,遍历第一个数组。当你在第一个数组中遇到小于第二个数组中的下一个条目但不等于它的条目时,你将它们注销。
const arrOne = [2,3,10,7,9,15,7,15,21,1].sort((a,b)=>a-b);const arrTwo = [3,15,1,2,21].sort((a,b)=>a-b);
var i1 = 0;for(var i2 = 0; i2 < arrTwo.length; i2++) {while(arrOne[i1] < arrTwo[i2+1]) {if(arrOne[i1] != arrTwo[i2]) {console.log(arrOne[i1]);}i1++;}}

One Liners

const unique = (a) => [...new Set(a)];const uniqueBy = (x,f)=>Object.values(x.reduce((a,b)=>((a[f(b)]=b),a),{}));const intersection = (a, b) => a.filter((v) => b.includes(v));const diff = (a, b) => a.filter((v) => !b.includes(v));const symDiff = (a, b) => diff(a, b).concat(diff(b, a));const union = (a, b) => diff(a, b).concat(b);
const a = unique([1, 2, 3, 4, 5, 5]);console.log(a);const b = [4, 5, 6, 7, 8];
console.log(intersection(a, b), diff(a, b), symDiff(a, b), union(a, b));
console.log(uniqueBy([{ id: 1, name: "abc" },{ id: 2, name: "xyz" },{ id: 1, name: "abc" },],(v) => v.id));
const intersectionBy = (a, b, f) => a.filter((v) => b.some((u) => f(v, u)));
console.log(intersectionBy([{ id: 1, name: "abc" },{ id: 2, name: "xyz" },],[{ id: 1, name: "abc" },{ id: 3, name: "pqr" },],(v, u) => v.id === u.id));
const diffBy = (a, b, f) => a.filter((v) => !b.some((u) => f(v, u)));
console.log(diffBy([{ id: 1, name: "abc" },{ id: 2, name: "xyz" },],[{ id: 1, name: "abc" },{ id: 3, name: "pqr" },],(v, u) => v.id === u.id));

TypeScript

游乐场链接

const unique = <T>(array: T[]) => [...new Set(array)];

const intersection = <T>(array1: T[], array2: T[]) =>array1.filter((v) => array2.includes(v));

const diff = <T>(array1: T[], array2: T[]) =>array1.filter((v) => !array2.includes(v));

const symDiff = <T>(array1: T[], array2: T[]) =>diff(array1, array2).concat(diff(array2, array1));

const union = <T>(array1: T[], array2: T[]) =>diff(array1, array2).concat(array2);

const intersectionBy = <T>(array1: T[],array2: T[],predicate: (array1Value: T, array2Value: T) => boolean) => array1.filter((v) => array2.some((u) => predicate(v, u)));

const diffBy = <T>(array1: T[],array2: T[],predicate: (array1Value: T, array2Value: T) => boolean) => array1.filter((v) => !array2.some((u) => predicate(v, u)));

const uniqueBy = <T>(array: T[],predicate: (v: T, i: number, a: T[]) => string) =>Object.values(array.reduce((acc, value, index) => {acc[predicate(value, index, array)] = value;return acc;}, {} as { [key: string]: T }));

如果你有两个对象列表

const people = [{name: 'cesar', age: 23}]const morePeople = [{name: 'cesar', age: 23}, {name: 'kevin', age: 26}, {name: 'pedro', age: 25}]
let result2 = morePeople.filter(person => people.every(person2 => !person2.name.includes(person.name)))
function array_diff(array1, array2) {let returnArray = [];$.each(array1, function(index, value) {let findStatus = false;if (Array.isArray(array2)) {$.each(array2, function(index2, value2) {if (value == value2) findStatus = true;});} else {if (value == array2) {findStatus = true;}}
if (findStatus == false) {returnArray.push(value);}});return returnArray;}
function diffArray(arr1, arr2) {const newArr = [];
// arr1 match to arr2arr1.map((item)=>{if(arr2.indexOf(item)<0){console.log(item)newArr.push(item)}})
// arr2 match to arr1arr2.map((item)=>{if(arr1.indexOf(item)<0){newArr.push(item)}})
return newArr;}

衍射阵列([1,2,3,5],[1,2,3,4,5])

输出:: [4]

const dbData = [{name:'ally'},{name:'James'}]const localData = [{name:'James'}]
const diff = dbData.filter(a =>!localData.some(b => { return a.name === b.name}))
const a1 = ['a', 'b', 'c', 'd'];const a2 = ['a', 'b'];
const diffArr = a1.filter(o => !a2.includes(o));
console.log(diffArr);

输出:

[ 'a', 'b' ]