How to split two overlapping ranges?

Looking for away to split two overlapping ranges when they overlap.

This is my current progress using typescript,

type Range = {
  start: number;
  end: number;
};
function splitOverlap(a: Range, b: Range): Range[][] {
  let result = [];
  const intersect = {
    start: Math.max(a.start, b.start),
    end: Math.min(a.end, b.end),
  };

  let a1: Range;
  let a2: Range;

  if (a.start >= intersect.start) {
    a1 = {
      start: a.start,
      end: Math.min(a.end, intersect.end),
    };

    a2 = {
      start: Math.max(a.start, intersect.start),
      end: Math.min(a.end, intersect.end),
    };
  } else if (a.start < intersect.start) {
    a1 = {
      start: a.start,
      end: Math.min(a.end, intersect.end),
    };

    a2 = {
      start: intersect.start,
      end: Math.min(a),
    };
  }

  return [
    [a1, a2],
    [b, b],
  ];
}

/* 
    Input
    A  |-------------|
    B         |-------------|

    Output
    A |-------|------|
    B         |------|------|

    Input
    A  |-------------|
    B     |-------|

    Output
    A  |--|-------|--|
    B     |-------|

*/

I am not required to do any merging, just splitting when there’s overlap.

My split function first find the intersect between the ranges, then using the intersect data I think I can split the two input ranges. I don’t know what is the best way to do it.

Answer

I finally did this

function splitOverlap(a: Range, b: Range): [Range[], Range[]] {
        const intersect: Range = {
            start: Math.max(a.start, b.start),
            end: Math.min(a.end, b.end),
        };

        const createRange = (range: Range, intersect: Range): Range[] => {
            const ranges = [...Object.values(getRange(range)), ...Object.values(intersect)];
            const uniqRanges = uniq(ranges.sort());
            const result = [];

            for (let i = 1; i < uniqRanges.length; i++) {
                const current = uniqRanges[i];
                const pre = uniqRanges[i - 1];

                result.push({
                    ...range,
                    start: pre,
                    end: current,
                });
            }

            return result;
        };

        const getRange = <T = any>({ start, end }: Range & T): Range => {
            return {
                start,
                end,
            };
        };

        const split1 = createRange(a, intersect);
        const split2 = createRange(b, intersect);

        return [split1, split2];
    }