是否有一种方法可以在JavaScript中返回两个数组之间的差异?
例如:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
是否有一种方法可以在JavaScript中返回两个数组之间的差异?
例如:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
当前回答
转换为字符串对象类型:
[1, 1].toString() === [1, 1].toString(); // true
其他回答
简单地比较所有值,并返回数组与不重复的值。
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!"
所选的答案只对了一半。您必须比较数组的两种方式才能得到完整的答案。
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' ]
纯JavaScript解决方案(没有库) 与旧浏览器兼容(不使用过滤器) O (n ^ 2) 可选的fn回调参数,用于指定如何比较数组项
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(', ') );
纯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或稀疏数组,那么所有示例的行为都可能令人惊讶或不明显。(对于大多数用途来说,这并不重要。)
对于想要从一个数组中减去另一个数组的人的回应…
如果不超过1000个元素试试这个…
设置一个新变量来复制Array01,并将其命名为Array03。
现在,使用冒泡排序算法比较Array01和Array02的元素,并在找到匹配时进行比较 对Array03执行以下操作…
if (Array01[x]==Array02[y]) {Array03.splice(x,1);}
注意:我们正在修改Array03而不是Array01,这样就不会搞砸冒泡排序的嵌套循环!
最后,用一个简单的赋值操作将Array03的内容复制到Array01,就完成了。