Así que estoy trabajando en un proyecto que compara diferentes arreglos. Está funcionando casi por completo, sin embargo, tengo un problema. Digamos que en esta situación, a y b son dos búsquedas diferentes que contienen datos de matriz. Los datos son en su mayoría los mismos, sin embargo, uno está ligeramente más actualizado que el otro (el no actualizado es esencialmente un subconjunto). El código que tengo aquí abajo es este:
async function dataDetect() { let fetchA = await fetch('https://a/data'); let fetchB = await fetch('https://b/data'); let dataA = await fetchA.json(); let dataB = await fetchB.json(); let differenceDetector = (dataA, dataB) => { let compareA = new Set(dataA); for (const x of new Set(dataB)) { if (compareA.has(x)) { compareA.delete(x); } else { compareA.add(x); } } return Array.from(compareA); }; let detected = differenceDetector(dataA, dataB); console.log('All differences script detected: ',{detected}); } dataDetect(); Y casi todo está funcionando. Sin embargo, tengo un gran problema. Por alguna razón, cada vez que ejecuto esto, la matriz total es en realidad ambas matrices combinadas, y nunca eliminó los elementos comunes. Estoy seguro de que hay una manera de solucionar esto, pero he probado varias combinaciones y ninguna de ellas ha funcionado completamente. Mi problema es algo así (estas no son las matrices reales en mi cosa): dataA=['Violet','Orange','Plumage','Crimson'] and dataB=['Violet','Orange','Plumage','Crimson','Maroon'] . La consola registra esto: ['Violet','Orange','Plumage','Crimson','Violet','Orange','Plumage','Crimson','Maroon'] . Mi registro final es, literalmente, solo las dos matrices apiladas. Esto funciona con arreglos normales, pero no con recuperaciones. ¿Por qué sucede esto y alguien puede explicar cómo solucionarlo?
let differenceDetector = (dataA, dataB) => { let compareA = new Set(dataA); for (const x of new Set(dataB)) { if (compareA.has(x)) { compareA.delete(x); } else { compareA.add(x); } } return Array.from(compareA); }; const dataB = ['Violet', 'Orange', 'Plumage', 'Crimson', 'Maroon']; const dataA = ['Violet', 'Orange', 'Plumage', 'Crimson']; console.log(differenceDetector(dataA, dataB));La distinción entre matrices de objetos y cadenas tiene que ver con cómo se prueba la igualdad. El método Set has() envuelve una prueba de igualdad (como === ) que funciona para tipos inmutables pero requiere generalización para comparar objetos
Esta función de intersección permite que la persona que llama pase un predicado arbitrario. La persona que llama puede usarlo para realizar una prueba de equivalencia en objetos.
function differenceDetector(arrayA, arrayB, test) { test = test || ((a, b) => a === b); // default to deep equality
return arrayA.filter(a => !arrayB.find(b => test(a,b))); } // this works as expected for strings... const a = ['Violet', 'Orange', 'Plumage', 'Crimson', 'Maroon']; const b = ['Violet', 'Orange', 'Plumage', 'Crimson']; console.log(differenceDetector(a, b)); // and it also works for objects... const c = [{ id: 1 }, { id: 2}, { id: 3 }, { id: 4 }]; const d = [{ id: 1 }, { id: 2}, { id: 3 }]; const test = (a, b) => a.id === b.id; // note that we pass an equivalence predicate "test" // without it, the default "===" test will give the OP's undesired result console.log(differenceDetector(c, d, test));Tenga en cuenta que esta implementación, como los OP, no es conmutativa. La diferencia encontrada son elementos del primer arreglo que no están en el segundo, según un predicado dado.
También tenga en cuenta que comparar objetos completos por equivalencia (todas las claves y valores son equivalentes) es un tema complicado. Una forma barata de codificar, aunque tal vez no sea tan barata en tiempo de ejecución, es comparar las codificaciones JSON...
const wholeObjectTest = (a, b) => JSON.stringify(a) === JSON.stringify(b);