En examinant un grand nombre de ces solutions, on constate qu'elles conviennent parfaitement pour les petits cas. Mais lorsque l'on passe à un million d'éléments, la complexité temporelle commence à devenir ridicule.
A.filter(v => B.includes(v))
Cela commence à ressembler à une solution O(N^2). Puisqu'il existe une solution O(N), utilisons-la, vous pouvez facilement la modifier pour qu'elle ne soit pas un générateur si vous n'êtes pas à jour sur votre runtime JS.
function *setMinus(A, B) {
const setA = new Set(A);
const setB = new Set(B);
for (const v of setB.values()) {
if (!setA.delete(v)) {
yield v;
}
}
for (const v of setA.values()) {
yield v;
}
}
a = [1,2,3];
b = [2,3,4];
console.log(Array.from(setMinus(a, b)));
Bien que cette solution soit un peu plus complexe que beaucoup d'autres, elle est beaucoup plus rapide lorsque vous avez de grandes listes.
Jetons un coup d'œil rapide à la différence de performance, en l'exécutant sur un ensemble de 1 000 000 d'entiers aléatoires entre 0...10 000, nous obtenons les résultats de performance suivants.
setMinus time = 181 ms
diff time = 19099 ms
function buildList(count, range) {
result = [];
for (i = 0; i < count; i++) {
result.push(Math.floor(Math.random() * range))
}
return result;
}
function *setMinus(A, B) {
const setA = new Set(A);
const setB = new Set(B);
for (const v of setB.values()) {
if (!setA.delete(v)) {
yield v;
}
}
for (const v of setA.values()) {
yield v;
}
}
function doDiff(A, B) {
return A.filter(function(x) { return B.indexOf(x) < 0 })
}
const listA = buildList(100_000, 100_000_000);
const listB = buildList(100_000, 100_000_000);
let t0 = process.hrtime.bigint()
const _x = Array.from(setMinus(listA, listB))
let t1 = process.hrtime.bigint()
const _y = doDiff(listA, listB)
let t2 = process.hrtime.bigint()
console.log("setMinus time = ", (t1 - t0) / 1_000_000n, "ms");
console.log("diff time = ", (t2 - t1) / 1_000_000n, "ms");