JavaScript实现从范围数组A中减去范围数组B的可用代码需求
实现范围数组相减的JavaScript代码
以下是直接可用的代码,实现将范围数组B中的范围从数组A中剔除的逻辑:
// 合并重叠或相邻的范围,简化后续计算 function mergeRanges(ranges) { if (ranges.length === 0) return []; // 按起始值排序 const sorted = [...ranges].sort((a, b) => a.start - b.start); const merged = [sorted[0]]; for (let i = 1; i < sorted.length; i++) { const last = merged[merged.length - 1]; const current = sorted[i]; // 当前范围和最后一个合并范围重叠或连续,合并它们 if (current.start <= last.end) { last.end = Math.max(last.end, current.end); } else { merged.push(current); } } return merged; } // 用单个范围切割范围数组,返回切割后的新数组 function subtractSingleRange(ranges, subtractRange) { const result = []; for (const range of ranges) { // 要减去的范围在当前范围左边,无交集,直接保留当前范围 if (subtractRange.end <= range.start) { result.push(range); continue; } // 要减去的范围在当前范围右边,无交集,直接保留当前范围 if (subtractRange.start >= range.end) { result.push(range); continue; } // 要减去的范围完全覆盖当前范围,丢弃当前范围 if (subtractRange.start <= range.start && subtractRange.end >= range.end) { continue; } // 要减去的范围在当前范围左侧,保留右侧剩余部分 if (subtractRange.start <= range.start && subtractRange.end < range.end) { result.push({ start: subtractRange.end, end: range.end }); continue; } // 要减去的范围在当前范围右侧,保留左侧剩余部分 if (subtractRange.start > range.start && subtractRange.end >= range.end) { result.push({ start: range.start, end: subtractRange.start }); continue; } // 要减去的范围在当前范围中间,分成左右两部分保留 if (subtractRange.start > range.start && subtractRange.end < range.end) { result.push({ start: range.start, end: subtractRange.start }); result.push({ start: subtractRange.end, end: range.end }); } } return result; } // 主函数:将B的所有范围从A中减去 function subtractRanges(A, B) { // 先合并A的范围,避免重复处理重叠部分 let mergedA = mergeRanges(A); // 逐个用B中的范围切割合并后的A for (const bRange of B) { mergedA = subtractSingleRange(mergedA, bRange); } // 过滤掉无效范围(起始值大于等于结束值的情况) return mergedA.filter(range => range.start < range.end); } // 测试示例 const A = [ { start: 10, end: 30 }, { start: 30, end: 60 } ]; const B = [ { start: 5, end: 20 }, { start: 23, end: 27 }, { start: 30, end: 80 }, ]; console.log(subtractRanges(A, B)); // 输出:[{ start: 20, end: 23 }, { start: 27, end: 30 }]
代码说明:
- mergeRanges函数:先对A的范围按起始值排序,合并重叠或连续的范围(比如示例中的A会被合并成
[{ start:10, end:60 }]),减少后续切割逻辑的复杂度。 - subtractSingleRange函数:处理单个B范围对当前结果数组的切割,分6种交集情况判断,保留剩余的有效范围。
- subtractRanges主函数:先合并A的范围,再依次用每个B的范围切割,最后过滤掉无效范围,得到最终结果。
内容的提问来源于stack exchange,提问作者zheka737
相关产品推荐
相关产品推荐

