Tengo dos listas:
let originalDocs = [ { id: "sara", date: new Date("01/01/2022") }, { id: "vic", date: new Date("10/26/2020") } ]; let newDocs = [ { id: "vic", date: new Date("01/02/2022") }, { id: "raul", date: new Date("05/05/2021") } ];Necesito mezclar ambas listas, ordenando por fecha (en orden descendente) y sin repeticiones.
Para ello, he decidido:
Este es mi código actual:
function removeIntersection(originalDocs, newDocs) { return originalDocs.filter((originalDoc) => { const index = newDocs.findIndex( (newDoc) => newDoc.id === originalDoc.id ); return index === -1; }); } function mixInOrder(originalDocs, newDocs) { return [...newDocs, ...originalDocs] .sort((a, b) => b.date - a.date); } // // MAIN // let originalDocs = [ { id: "sara", date: new Date("01/01/2022") }, { id: "vic", date: new Date("10/26/2020") } ]; let newDocs = [ { id: "vic", date: new Date("01/02/2022") }, { id: "raul", date: new Date("05/05/2021") } ]; const result = mixInOrder( removeIntersection(originalDocs, newDocs), newDocs ); console.log(result);¿Cómo puedo hacer lo mismo de una manera más óptima, es decir, sin la necesidad de fusionar (usando la sintaxis extendida) la lista antes de ordenarla o eliminar la intersección en O(1).
Quiero decir, ¿es posible simplemente insertar para evitar la copia?
Puede lograr fácilmente el resultado usando Set y reduce como:
originalDocs y luego newDocs .reduce para recorrer la matriz recién creada y luego filtrar los objetos.Puede usar
Setpara verificar la existencia de una clave de manera eficiente
let originalDocs = [ { id: 'sara', date: new Date('01/01/2022'), }, { id: 'vic', date: new Date('10/26/2020'), }, ]; let newDocs = [ { id: 'vic', date: new Date('01/02/2022'), }, { id: 'raul', date: new Date('05/05/2021'), }, ]; const set = new Set(); const result = [...originalDocs, ...newDocs].reduce((acc, curr) => { if (!set.has(curr.id)) { acc.push(curr); set.add(curr.id); } return acc; }, []) .sort((a, b) => b.date - a.date); console.log(result);Aquí se explica cómo hacer esto usando un mapa JS, donde usa la id como identificador:
let originalDocs = [ { id: "sara", date: new Date("01/01/2022") }, { id: "vic", date: new Date("10/26/2020") } ]; let newDocs = [ { id: "vic", date: new Date("01/02/2022") }, { id: "raul", date: new Date("05/05/2021") } ]; const map = new Map(originalDocs.map(el => [el.id, el])); newDocs.forEach(el => map.set(el.id, el)); const sorted = [...map.values()].sort((a, b) => a.date - b.date); console.log(sorted) Esto anula cualquier entrada de originalDocs con una entrada de newDocs si tienen la misma id .