Algoritmo que combina los mismos objetos a una sola llave común -- javascript camp codereview Relacionados El problema

Algorithm that combines same objects to single common key


2
vote

problema

Español

Escribí este algoritmo, pero me preguntaba si había alguna forma en que puedo hacerlo menos "caro". El algoritmo necesita transformar esta estructura de datos:

  const deliveryHours = {   monday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },   ],   tuesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 3,         minute: 0,       },     },   ],   wednesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 4,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 1,         minute: 0,       },     },   ], }   

a:

  [ { hours: { from: 3, to: 4 }, wednesday: true },   { hours: { from: 3, to: 6 }, tuesday: true, monday: true },   { hours: { from: 5, to: 1 }, wednesday: true },   { hours: { from: 5, to: 3 }, tuesday: true } ]   

Este es mi intento, claramente no es la mejor manera de hacerlo, pero estoy teniendo dificultades para encontrar otra forma:

  Flexbox0  
Original en ingles

I wrote this algorithm but i was wondering if there was any way i can make it less 'expensive'. The algorithm needs to transform this data structure:

const deliveryHours = {   monday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },   ],   tuesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 3,         minute: 0,       },     },   ],   wednesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 4,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 1,         minute: 0,       },     },   ], } 

to:

[ { hours: { from: 3, to: 4 }, wednesday: true },   { hours: { from: 3, to: 6 }, tuesday: true, monday: true },   { hours: { from: 5, to: 1 }, wednesday: true },   { hours: { from: 5, to: 3 }, tuesday: true } ] 

This is my attempt, it is clearly not the best way to go about it but im having a hard time finding another way:

const deliveryHours = {   monday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },   ],   tuesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 6,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 3,         minute: 0,       },     },   ],   wednesday: [     {       start: {         hour: 3,         minute: 0,       },       end: {         hour: 4,         minute: 0,       },     },     {       start: {         hour: 5,         minute: 0,       },       end: {         hour: 1,         minute: 0,       },     },   ], }    const mapDeliveryHours = (deliveryHours) => {   const result = {};   for (let i = 0; i < Object.keys(deliveryHours).length; i += 1) {     const day = Object.keys(deliveryHours)[i];      const ranges = deliveryHours[day];      for (let j = 0; j < ranges.length; j++) {       const range = ranges[j];        result[range.start.hour.toString() + range.end.hour.toString()] = {         hours: {           from: range.start.hour,           to: range.end.hour,         },         [day]: true,       };        for (let k = 0; k < Object.keys(deliveryHours).length; k++) {         const innerDay = Object.keys(deliveryHours)[k];         const innerRanges = deliveryHours[innerDay];          for (let l = 0; l < innerRanges.length; l++) {           const innerRange = innerRanges[l];           if (day !== innerDay             && innerRange.start.hour === range.start.hour             && innerRange.end.hour === range.end.hour           ) {             result[range.start.hour.toString() + range.end.hour.toString()] = {               ...result[range.start.hour.toString() + range.end.hour.toString()],               [innerDay]: true,             };           }         }       }     }   }   return Object.values(result); };  console.log(mapDeliveryHours(deliveryHours))
  

Lista de respuestas

2
 
vote

No es mucho menos código, pero creo que es más claro y más fácil de razonar sobre: ​​

  arr5  

Básicamente, he robado el foreach y la transformar desde mi biblioteca: Goodcore pero escrito todo en JavaScript aquí para que no tengas que usarlo.

 

It is not much less code but I believe it is clearer and easier to reason about:

function forEach(target, fn) {     var keys = Object.keys(target);     var key;     var i = -1;     while (++i < keys.length) {         key = keys[i];         fn(target[key], key);     } } function transform(target, fn, accumulator) {     if (accumulator === undefined) {         accumulator = Object.create(target);     }     forEach(target, function (value, key) {         return fn(accumulator, value, key);     });     return accumulator; } function aggregateHours(hours) {     var agg = [];     return transform(hours, function (result, spans, day) {         spans.forEach(function (span) {             var found = agg.find(function (el, i) { return el.hours.from === span.start.hour && el.hours.to === span.end.hour; });             if (found) {                 found[day] = true;             }             else {                 agg.push({ hours: { from: span.start.hour, to: span.end.hour } });                 agg[agg.length - 1][day] = true;             }         });     }, agg); }  aggregateHours(deliveryHours); 

Basically I have stolen the foreach and transform from my library: goodcore but written it all in javascript here so that you don't have to use it.

 
 
   
   
0
 
vote

uno a muchos, datos indexados

Cuando necesita datos organizados para que haya una relación de una a muchas personas de un índice a los datos que puede usar un MAP para hacer el trabajo duro de garantizar que la otra regla se quede verdadera.

Un mapa tiene datos que se hace referencia a través de un índice único (o clave como la gente de JS le gusta llamarlo). Los datos para sujetar serán un objeto que contenga los días nombrados, y los tiempos de apertura y cierre.

Transformar los tiempos de entrega Objeto a la matriz

En este caso, el índice es el tiempo de apertura y los datos son los días que tienen ese tiempo abierto.

Deberá crear una tecla de índice que identifique de manera única un tiempo de apertura específico. Una cadena simple hará arr6

Utilice el índice para consultar el mapa para un objeto asociado.

Si no hay ningún objeto para ese índice, cree un nuevo objeto que contenga el día y la información adicional relacionada con el índice, luego agreguela al mapa usando el índice como la clave.

Si existe el objeto índice, solo agregue el día abierto al objeto.

Una vez que haya recopilado los datos, luego extraiga los valores del mapa al tipo de datos que desea. En este caso, una matriz, un artículo de cada índice único (tiempo de apertura)

Ejemplo

la función se verá como

  arr7  

Ordenar el resultado

Lo anterior crea una matriz que es similar, pero el orden no es el mismo. Si lo necesita, se ordenó de más temprano más largo para más tarde, puede ordenar la matriz de devolución de la siguiente manera

  arr8  
 

One to many, indexed data

When you need data organised so that there is a one to many relationship from an index to the data you can use a Map to do the hard work of ensuring that the one to many rule stays true.

A map holds data that is referenced via a unique index (or key as JS people like to call it). The data to hold will be an object containing named days, and the times of open and close.

Transform delivery times object to array

In this case the index is the opening time and the data is the days that have that time open.

You will need to create a index key that uniquely identifies a specific opening time. A simple string will do index = start + "-" end;

Use the index to query the map for an object associated.

If no object for that index, create a new object that contains the day and additional information pertaining to the index, then add it to the map using the index as the key.

If the index object exists then just add the open day to the object.

Once you have collected the data you then extract the values from the map to the data type you want. In this case an array, one item of each unique index (opening time)

Example

The function will look like

function transformDeliveryTimes(data) {     const hours = new Map();      const addOpen = (time, day) => {         const from = time.start.hour, to = time.end.hour;         const index = from + "-" + to;         const open = hours.get(index);         if (open) { open[day] = true }         else { hours.set(index, {hours : {from, to}, [day] : true}) }     }      for (const [day, times] of Object.entries(data)) {         for (const time of times) { addOpen(time, day) }     }     return [...hours.values()]; } const openTimesArray = transformDeliveryTimes(deliveryHours); 

Sort the result

The above creates an array that is similar but the order is not the same. If you need it sorted from earliest longest to latest longest you can sort the return array as follows

openTimesArray.sort((a,b)=> {     const dif = a.hours.from - b.hours.from;     return dif ? dif : a.hours.to - b.hours.to; }); 
 
 
       
       

Relacionados problema

3  Página web basada en una muestra de un libro  ( Web page based on a sample from a book ) 
He creado una página web basada en una muestra de un libro. Funciona bien, pero parece haber sido demasiado complicado. dt4 ¿Es posible mejorar la clari...

5  Función de movimiento para un juego  ( Move function for a game ) 
Tengo una función PackageSubpackageSubpackageName6 en este juego que estoy haciendo. Funciona bien, pero me gustaría reducir un poco su tamaño. PackageSu...

2  IMACROS BOT para realizar refrescos  ( Imacros bot for performing refreshes ) 
Estoy tratando de simplificar este código. Parece que todo funciona como debería; Sin embargo, cuando en el bucle de actualización de Imacro, parece un poco i...

3  Función de estilo sortable jquery  ( Jquery sortable style function ) 
Esta es una función de clasificación básica escrita en jQuery que mueve los elementos en la DOM alrededor para crear espacios vacíos para un gotpable (). Como...

10  "Stardust" Simulador 2D Gravity - Seguimiento 1: Los planetas  ( Stardust 2d gravity simulator follow up 1 the planets ) 
Este es un seguimiento para el juego de gravedad del simulador 2D pregunta. Desde entonces, he desarrollado mis habilidades de JavaScript, y ahora esto...

7  Merge Sort en JavaScript  ( Merge sort in javascript ) 
Implementé este tipo de fusión en JS y noté que para los números de enteros aleatorios es mucho más rápido que la construcción en funciones de tipo de todos l...

7  Elementos de anidación con apendchild  ( Nesting elements with appendchild ) 
Quiero hacer un navegación que se vea así: <nav class="socialmediaicons"> <ul> <li> <a> <img> </a> </li> </ul> </nav> ...

2  Limpiando una galería de imágenes rotativas  ( Cleaning up a rotating image gallery ) 
He creado una pequeña galería de imágenes para la web. Me propuse querer 3 cosas. 1. Toda la galería tenía una capacidad de respuesta a nivel básica. 2. La ga...

3  Convertir un estado de hash a un objeto JavaScript  ( Converting a state from hash into a javascript object ) 
Este código obtiene un estado desde una parte de hash de una cadena de consulta, convierte la parte de hash a un objeto JavaScript y luego intenta obtener un ...

1  Enviando la página web actual a un sitio de marcadores  ( Submitting the current webpage to a bookmarking site ) 
Me gustaría escuchar sus comentarios sobre el siguiente enlace que permite a los usuarios agregar un enlace a un sitio web. Leí que join()5 es sugerido en...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos