const array1 = [2,1,3,5,2,1,3,5];
const array2 = [4,3,2,6,7,4,3,2,6,7];
function diff(arr1, arr2) {
const dontAddDuplicates = true;
arr1.sort();
arr2.sort();
let a1 = [];
let a2 = [];
let i = 0;
let j = 0;
while (i < array1.length || j < array2.length) {
if (i >= arr1.length) {
if (!dontAddDuplicates || (a2.length == 0 || a2[a2.length - 1] != arr2[j])) {
a2.push(arr2[j]);
}
j++;
} else if (j >= array2.length) {
if (!dontAddDuplicates || (a1.length == 0 || a1[a1.length - 1] != arr1[i])) {
a1.push(arr1[i]);
}
i++;
} else if (arr1[i] < arr2[j]) {
if (!dontAddDuplicates || (a1.length == 0 || a1[a1.length - 1] != arr1[i])) {
a1.push(arr1[i]);
}
i++;
} else if (arr2[j] < arr1[i]) {
if (!dontAddDuplicates || (a2.length == 0 || a2[a2.length - 1] != arr2[j])) {
a2.push(arr2[j]);
}
j++;
} else {
// Same value, do nothing
i++;
j++;
}
}
return [a1, a2];
}
console.log(diff(array1, array2));
// OUTPUT: [[1, 5], [4, 6, 7]]
Here's another potential implementation using sorting, but it has the side effect of leaving array1 and array2 in a sorted fashion. Sorting allows you to avoid needing to rescan the other array every time. If they are already sorted then great you can skip this step. If the side effect is a problem, then use a deep copy of array1 and array2 before calling sort.
Flip dontAddDuplicates
if you want duplicates or not. I notice the other implementations don't account for that, but easy enough to add.
Run time should be: SORT N + SORT M + N + M = SORT N = N LOG N depending on your input sizes and distributions SORT will be the significant O Notation https://www.bigocheatsheet.com/
https://jsfiddle.net/buscgtL2/1/
If you want to do it in N + M + N + M = N time you can use this implementation which uses a hash map instead of sorting. This has a disadvantage on memory space.
const array1 = [2,1,3,5,2,1,3,5];
const array2 = [4,3,2,6,7,4,3,2,6,7];
function diff(arr1, arr2) {
let dontAddDuplicates = true;
let a1 = [];
let a2 = [];
let a1hash = {};
let a2hash = {};
for (let i = 0; i < arr1.length; i++) {
a1hash[arr1[i]] = 0;
}
for (let i = 0; i < arr2.length; i++) {
a2hash[arr2[i]] = 0;
}
for (let i = 0; i < arr1.length; i++) {
if (!a2hash.hasOwnProperty(arr1[i])) {
if (!dontAddDuplicates || a1hash[arr1[i]] == 0) {
a1hash[arr1[i]] = 1;
a1.push(arr1[i]);
}
}
}
for (let i = 0; i < arr2.length; i++) {
if (!a1hash.hasOwnProperty(arr2[i])) {
if (!dontAddDuplicates || a2hash[arr2[i]] == 0) {
a2hash[arr2[i]] = 1;
a2.push(arr2[i]);
}
}
}
return [a1, a2];
}
console.log(diff(array1, array2));
//OUTPUT: [[1, 5], [4, 6, 7]]
https://jsfiddle.net/2945y3an/1/
The worse performance would be any algorithm where for every N element you scan array M searching for a match. This would be N * M = N^2