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

列表间移动数字时如何高效重新计算range区间

方案思路

直接操作区间对象完成增删改,无需展开大区间的全量数字,仅需要对要移动的少量数字做区间转换,内存占用和性能都远优于原方案,同时兼容你现有的数字列表输入格式。

执行步骤

步骤1:将要移动的数字转为连续区间

即使输入是零散数字列表,也仅需要用你现有getRanges函数对这部分小数据做区间转换:

// 比如要移动的数字是[5000010,5000011,...5000020],直接转成区间
const moveRanges = getRanges(moveNumbers)

这一步处理的是你要移动的少量数字,完全不存在内存占用问题。

步骤2:更新移出列表的区间

遍历移出列表的原有区间,和moveRanges中的每一段做比对,只保留未被移出的部分:

function removeRanges(originalRanges, removeRanges) {
  let result = [...originalRanges]
  for (const rm of removeRanges) {
    const newResult = []
    for (const ori of result) {
      // 完全不重叠:直接保留
      if (ori.upper < rm.lower || ori.lower > rm.upper) {
        newResult.push(ori)
        continue
      }
      // 移出区间覆盖头部:保留尾部
      if (ori.lower < rm.lower && ori.upper <= rm.upper) {
        newResult.push({ lower: ori.lower, upper: rm.lower - 1 })
      }
      // 移出区间覆盖尾部:保留头部
      else if (ori.lower >= rm.lower && ori.upper > rm.upper) {
        newResult.push({ lower: rm.upper + 1, upper: ori.upper })
      }
      // 移出区间切在中间:拆成两段保留
      else if (ori.lower < rm.lower && ori.upper > rm.upper) {
        newResult.push({ lower: ori.lower, upper: rm.lower - 1 })
        newResult.push({ lower: rm.upper + 1, upper: ori.upper })
      }
      // 完全覆盖:直接丢弃,不用加
    }
    result = newResult
  }
  // 按lower升序排序
  return result.sort((a, b) => a.lower - b.lower)
}

步骤3:更新移入列表的区间

把要移动的区间加入移入列表后,做一次相邻区间合并即可:

function addRanges(originalRanges, addRanges) {
  // 合并所有区间后排序
  const allRanges = [...originalRanges, ...addRanges].sort((a, b) => a.lower - b.lower)
  if (allRanges.length === 0) return []
  const merged = [allRanges[0]]
  for (let i = 1; i < allRanges.length; i++) {
    const current = allRanges[i]
    const last = merged[merged.length - 1]
    // 相邻区间连续则合并
    if (current.lower === last.upper + 1) {
      last.upper = current.upper
    } else {
      merged.push(current)
    }
  }
  return merged
}

示例验证

以你给出的从C列表移动5000010到5000020到B列表为例:

  1. 转换移动数字得到moveRanges = [{lower:5000010, upper:5000020}]
  2. 调用removeRanges(C的原有区间, moveRanges),得到处理后的C区间:
[
  {lower:5000001, upper:5000009},
  {lower:5000021, upper:6999900},
  {lower:9000000, upper:9999999}
]
  1. 调用addRanges(B的原有区间, moveRanges),得到处理后的B区间:
[
  {lower:13, upper:15},
  {lower:21,upper:30},
  {lower:34,upper:9999},
  {lower:5000010, upper:5000020}
]

和你预期的结果完全一致,全程没有展开任何大区间,仅处理了少量的区间对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:36:05