You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 }]

代码说明:

  1. mergeRanges函数:先对A的范围按起始值排序,合并重叠或连续的范围(比如示例中的A会被合并成[{ start:10, end:60 }]),减少后续切割逻辑的复杂度。
  2. subtractSingleRange函数:处理单个B范围对当前结果数组的切割,分6种交集情况判断,保留剩余的有效范围。
  3. subtractRanges主函数:先合并A的范围,再依次用每个B的范围切割,最后过滤掉无效范围,得到最终结果。

内容的提问来源于stack exchange,提问作者zheka737

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:48:20