是否有一种方法可以在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"]
当前回答
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;
其他回答
一个衬垫
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 ));
打印稿
操场上的链接
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 })
);
Samuel:“对于我的代码,我也需要删除副本,但我想这并不总是可取的。 我想主要的缺点是它可能会比较许多已经被拒绝的选择。”
当比较TWO列表、数组等,且元素小于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])}
根据之前的答案…取决于你是想要一个高效的还是“漂亮的联机”解决方案。
一般有三种方法……
"manual iterative" (using indexOf) - naive with O(n2) complexity (slow) 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; } "abstract iterative" (using filter and concat library methods) - syntactic sugar for manual iterative (looks nicer, still sucks) 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);})); } "using hashtable" (using object keys) - much more efficient - only O(n), but has slightly limited range of input array values 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; }
在jsperf上可以看到 https://jsperf.com/array-diff-algo
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)));
}
adaen对post(比较两个包含整数的数组JavaScript)的响应是关闭的:
有几个选项:
您可以将第二个数组的所有条目添加到hashmap中。然后遍历第一个数组中的条目,并记录hashmap中不存在的条目。
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));
另一个选择是对两个数组进行排序。然后迭代第二个数组。在其中,迭代第一个数组。当您遇到第一个数组中的条目小于第二个数组中的下一个条目但不等于它时,您将它们注销。
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++;
}
}