Algorithm that combines same objects to single common key 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) =&gt; {
  const result = {};
  for (let i = 0; i &lt; Object.keys(deliveryHours).length; i += 1) {
    const day = Object.keys(deliveryHours)[i];

    const ranges = deliveryHours[day];

    for (let j = 0; j &lt; 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 &lt; Object.keys(deliveryHours).length; k++) {
        const innerDay = Object.keys(deliveryHours)[k];
        const innerRanges = deliveryHours[innerDay];

        for (let l = 0; l &lt; innerRanges.length; l++) {
          const innerRange = innerRanges[l];
          if (day !== innerDay
            &amp;&amp; innerRange.start.hour === range.start.hour
            &amp;&amp; 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))
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 &lt; 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 &amp;&amp; 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.