Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

325
Vistas
¿Dividir una matriz de elementos de rango de fechas, cada uno con una marca de tiempo de inicio y finalización que pueden superponerse entre sí en matrices separadas de rangos que no se superponen?

Digamos que tengo una matriz como la siguiente, ¿cuál sería el mejor método para separarlos en matrices individuales si los tiempos se superponen? Estoy usando el momento, pero no estoy seguro de cómo abordar esto.

Sé que tengo que ordenar la matriz inicialmente.

datos:

 const timetable = [ { class: 'one', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, { class: 'two', start: '2021-11-16T010:00:00', end: '2021-11-16T11:00:00' }, { class: 'three', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, ];

esperado:

 const timetable = [ [ { class: 'one', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, { class: 'two', start: '2021-11-16T010:00:00', end: '2021-11-16T11:00:00' }, ], [ { class: 'three', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00', }, ], ];
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Un enfoque genérico tiene que funcionar recursivamente a través de cualquier timetable original dado (matriz de origen) para detectar/generar la mayor cantidad de tablas de tiempo, cada una de las cuales presenta solo elementos de rango de tiempo que no se superponen.

Una implementación recursiva se llamaría a sí misma repetidamente siempre que, dentro de una matriz procesada, aún se encuentren elementos de rango de tiempo superpuestos.

Parte del enfoque es que tal función autorrecursiva crea una copia superficial de la tabla de tiempo pasada y también la ordena exactamente una vez, en el momento de ser llamada inicialmente.

 function parseTime(value) { return new Date(value).getTime(); } function getParsedTimeRangeFromItem({ start, end }) { return { start: parseTime(start), end: parseTime(end), } } function orderByTimeRangeAscending(a, b) { const { start: aStart, end: aEnd } = getParsedTimeRangeFromItem(a); const { start: bStart, end: bEnd } = getParsedTimeRangeFromItem(b); return (aStart - bStart) || (aEnd - bEnd); } function createTimetablesOfNonOverlappingTimeRanges(timetable, result) { // at initial call time only ... if (!Array.isArray(result)) { // ... create the result array ... result = []; // ... and also a shallow and sorted copy // of the initially passed `timetable`. timetable = [...timetable].sort(orderByTimeRangeAscending); } const rejected = []; let idx = -1; let item, nextItem; while ( (item = timetable[++idx]) && (nextItem = timetable[idx + 1]) ) { // detect `nextItem` as overlapping time range item ... if (parseTime(item.end) > parseTime(nextItem.start)) { // ... and reject it from the `timetable` reference. rejected.push(timetable.splice((idx + 1), 1)[0]) --idx; } } // add the sanitized but mutated `timetable` to `result`. result.push(timetable); // in case of any rejected time range item trigger self recursion. if (rejected.length >= 1) { result = createTimetablesOfNonOverlappingTimeRanges(rejected, result); } return result; } const timetable = [ { class: 'one', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, { class: 'two', start: '2021-11-16T10:00:00', end: '2021-11-16T11:00:00' }, { class: 'three', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, { class: 'four', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, { class: 'five', start: '2021-11-16T10:00:00', end: '2021-11-16T11:00:00' }, { class: 'six', start: '2021-11-16T09:00:00', end: '2021-11-16T10:00:00' }, ]; console.log( '[...timetable].sort(orderByTimeRangeAscending) ...', [...timetable] .sort(orderByTimeRangeAscending) ); console.log( 'createTimetablesOfNonOverlappingTimeRanges(timetable) ...', createTimetablesOfNonOverlappingTimeRanges(timetable) ); console.log('un-mutated original source array ...', { timetable });
 .as-console-wrapper { min-height: 100%!important; top: 0; }

about 4 years ago · Juan Pablo Isaza Denunciar

0

Divídalo en partes más pequeñas y aborde cada problema. No estoy seguro de cuál es tu plan si terminas con varias clases superpuestas. Este código solo devuelve una matriz con dos elementos: clases únicas y clases superpuestas, no sigue agregando nuevos elementos para cada clase infractora.

 const timetable = [ { class: "one", start: "2021-11-16T09:00:00", end: "2021-11-16T10:00:00" }, { class: "two", start: "2021-11-16T10:00:00", end: "2021-11-16T11:00:00" }, { class: "three", start: "2021-11-16T09:00:00", end: "2021-11-16T10:00:00" }, ]; // get an object, return a new object with the times as // timestamps, rather than time strings // (you don't need Moment.JS, JavaScript has .getTime()) const parseTimes = el => { const hour = {...el}; hour.start = new Date(el.start).getTime(); hour.end = new Date(el.end).getTime(); return hour; }; // given two objects, see if one is fully before or after // another. If not, they overlap. const overlaps = (a, b) => { if (a.start <= b.start && a.end <= b.start) return false; if (a.end >= b.end && a.start >= b.end) return false; return true; }; // given an array and a starting place, figure out if any // of the objects overlap any of the previous objects const overlapsPrevious = (arr, idx) => { const a = parseTimes(arr[idx]); for (let ix = 0; ix <= idx; ix++) { const b = parseTimes(arr[ix]); if (a.class !== b.class && overlaps(a, b)) return true; } return false; }; // given an array, return a new array with non-overlaping // objects and objects that overlap const split = (arr) => { const unique = []; const overlap = []; for(let ix = 0; ix < arr.length; ix++) { if(overlapsPrevious(arr, ix)) overlap.push(arr[ix]); else unique.push(arr[ix]); } return [unique, overlap]; } // display the result console.log(split(timetable));

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda