es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Javascript – Mezclar dos arreglos de objetos ordenándolos por fecha y sin repeticiones

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, ordenándolas por fecha (en orden descendente) y sin repeticiones.

Para hacer eso, he decidido:

  1. Eliminar el conjunto de elementos del array original que están incluidos en el nuevo array (es decir, eliminar la intersección) sin modificar el array original.
  2. Mezclar el array resultante ordenándolo por fecha.

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 necesidad de fusionar (usando la sintaxis spread) la lista antes de ordenarla, o eliminar la intersección en O(1)?

Es decir, ¿es posible solo insertar en orden evitando la copia?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en JavaScript y algoritmos, es posible insertar los elementos de newDocs en originalDocs en orden sin necesidad de fusionar o eliminar la intersección. Esto se puede lograr utilizando un algoritmo de búsqueda binaria para encontrar el punto de inserción de cada elemento en newDocs e insertarlo en la posición correcta en originalDocs sin crear un nuevo array.

    Aquí está el código de la función mixInOrder revisada que logra esto:

    function mixInOrder(originalDocs, newDocs) {
      const len = originalDocs.length;
      for (let i = 0; i < newDocs.length; i++) {
        const newDoc = newDocs[i];
        let index = binarySearch(originalDocs, newDoc, 0, len - 1);
        // Saltar elementos en originalDocs con el mismo id que newDoc
        while (index < len && originalDocs[index].id === newDoc.id) {
          index++;
        }
        originalDocs.splice(index, 0, newDoc);
      }
      return originalDocs;
    }
    

    La función binarySearch es una implementación recursiva de la búsqueda binaria que devuelve el índice donde newDoc debe ser insertado en originalDocs para mantener el orden. Si newDoc ya existe en originalDocs, lo omitimos para evitar duplicados.

    function binarySearch(arr, x, start, end) {
      if (start > end) return start;
    
      const mid = Math.floor((start + end) / 2);
      if (x.date === arr[mid].date) return mid;
    
      if (x.date < arr[mid].date) {
        return binarySearch(arr, x, mid + 1, end);
      } else {
        return binarySearch(arr, x, start, mid - 1);
      }
    }
    

    El uso de esta función mixInOrder revisada evita crear un nuevo array al insertar los elementos en el orden correcto directamente en originalDocs, lo que resulta en un mejor rendimiento.

Comments are closed.