Built a tester to check just how fast some of the performance oriented answers are. Feel free to add some more. So far, Set
is both the simplest and fastest option (by bigger margins as the number of records increases), at least with simple Number
types.
const records = 10000, //max records per array
max_int = 100, //max integer value per array
dup_rate = .5; //rate of duplication
let perf = {}, //performance logger,
ts = 0,
te = 0,
array1 = [], //init arrays
array2 = [],
array1b = [],
array2b = [],
a = [];
//populate randomized arrays
for (let i = 0; i < records; i++) {
let r = Math.random(),
n = r * max_int;
if (Math.random() < .5) {
array1.push(n);
r < dup_rate && array2.push(n);
} else {
array2.push(n);
r < dup_rate && array1.push(n);
}
}
//simple deep copies short of rfdc, in case someone wants to test with more complex data types
array1b = JSON.parse(JSON.stringify(array1));
array2b = JSON.parse(JSON.stringify(array2));
console.log('Records in Array 1:', array1.length, array1b.length);
console.log('Records in Array 2:', array2.length, array2b.length);
//test method 1 (jsperf per @Pitouli)
ts = performance.now();
for (let i = 0; i < array2.length; i++)
if (array1.indexOf(array2[i]) === -1)
array1.push(array2[i]); //modifies array1
te = performance.now();
perf.m1 = te - ts;
console.log('Method 1 merged', array1.length, 'records in:', perf.m1);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1
//test method 2 (classic forEach)
ts = performance.now();
array2.forEach(v => array1.includes(v) ? null : array1.push(v)); //modifies array1
te = performance.now();
perf.m2 = te - ts;
console.log('Method 2 merged', array1.length, 'records in:', perf.m2);
//test method 3 (Simplest native option)
ts = performance.now();
a = [...new Set([...array1, ...array2])]; //does not modify source arrays
te = performance.now();
perf.m3 = te - ts;
console.log('Method 3 merged', a.length, 'records in:', perf.m3);
//test method 4 (Selected Answer)
ts = performance.now();
a = array1.concat(array2); //does not modify source arrays
for (let i = 0; i < a.length; ++i) {
for (let j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
te = performance.now();
perf.m4 = te - ts;
console.log('Method 4 merged', a.length, 'records in:', perf.m4);
//test method 5 (@Kamil Kielczewski)
ts = performance.now();
function K(arr1, arr2) {
let r = [],
h = {};
while (arr1.length) {
let e = arr1.shift(); //modifies array1
if (!h[e]) h[e] = 1 && r.push(e);
}
while (arr2.length) {
let e = arr2.shift(); //modifies array2
if (!h[e]) h[e] = 1 && r.push(e);
}
return r;
}
a = K(array1, array2);
te = performance.now();
perf.m5 = te - ts;
console.log('Method 5 merged', a.length, 'records in:', perf.m4);
array1 = JSON.parse(JSON.stringify(array1b)); //reset array1
array2 = JSON.parse(JSON.stringify(array2b)); //reset array2
for (let i = 1; i < 6; i++) {
console.log('Method:', i, 'speed is', (perf['m' + i] / perf.m1 * 100).toFixed(2), '% of Method 1');
}
_x000D_