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

JavaScript筛选两个对象的公共日期范围并截取对应timeline数据

JavaScript时序对象重叠区间提取方案

核心思路

利用输入数据的固有特性:每个对象的Date数组是连续递增、与timeline数组下标严格一一对应的有序数组,不需要写多层嵌套if判断逐值比对,只需要三步即可完成需求:

  • 预处理日期值为时间戳,规避字符串日期比较的隐式转换问题
  • 计算两个日期区间的交集边界:交集起点为两个对象日期起点的最大值,交集终点为两个对象日期终点的最小值
  • 定位交集边界在两个Date数组中的对应下标,直接用数组切片方法提取对应位置的timeline值即可

如果计算得到的交集起点大于终点,说明两个对象的日期范围完全无重叠,直接返回空结果即可。


可直接复用的实现代码

/**
 * 提取两个时序对象的重叠区间timeline数据
 * @param {Object} objA 第一个待比对对象,需包含Date、timeline属性
 * @param {Object} objB 第二个待比对对象,需包含Date、timeline属性
 * @returns {Object} 包含重叠区间的两个timeline数组、对应公共日期数组
 */
function getOverlapTimeline(objA, objB) {
  // 日期转时间戳工具
  const parseToTimestamp = (dateStr) => new Date(dateStr).getTime();
  const timestampsA = objA.Date.map(parseToTimestamp);
  const timestampsB = objB.Date.map(parseToTimestamp);

  // 取两个对象的日期起止边界
  const [startA, endA] = [timestampsA[0], timestampsA.at(-1)];
  const [startB, endB] = [timestampsB[0], timestampsB.at(-1)];

  // 计算重叠区间边界
  const overlapStart = Math.max(startA, startB);
  const overlapEnd = Math.min(endA, endB);

  // 无重叠直接返回空结构
  if (overlapStart > overlapEnd) {
    return { timelineA: [], timelineB: [], overlapDates: [] };
  }

  // 定位边界在两个数组中的下标
  const startIdxA = timestampsA.indexOf(overlapStart);
  const endIdxA = timestampsA.indexOf(overlapEnd);
  const startIdxB = timestampsB.indexOf(overlapStart);
  const endIdxB = timestampsB.indexOf(overlapEnd);

  // 切片提取目标数据
  const timelineA = objA.timeline.slice(startIdxA, endIdxA + 1);
  const timelineB = objB.timeline.slice(startIdxB, endIdxB + 1);
  const overlapDates = objA.Date.slice(startIdxA, endIdxA + 1);

  // 异常兜底校验
  if (timelineA.length !== timelineB.length) {
    console.warn("输入数据的Date数组存在非连续断档,请检查原始数据合法性");
  }

  return { timelineA, timelineB, overlapDates };
}

兼容优化方案

如果你的原始数据可能存在日期缺省、非严格连续的场景,可以把indexOf下标查找替换为有序数组专用的二分查找逻辑,查找效率更高,也能兼容个别日期缺失的异常场景:

// 有序数组二分查找目标值下标,找不到返回-1
function binarySearch(sortedArr, target) {
  let left = 0;
  let right = sortedArr.length - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (sortedArr[mid] === target) return mid;
    sortedArr[mid] < target ? (left = mid + 1) : (right = mid - 1);
  }
  return -1;
}

// 替换原代码中indexOf的调用即可
const startIdxA = binarySearch(timestampsA, overlapStart);
const endIdxA = binarySearch(timestampsA, overlapEnd);
const startIdxB = binarySearch(timestampsB, overlapStart);
const endIdxB = binarySearch(timestampsB, overlapEnd);

使用示例

// 比对数组中第1个和第2个对象的重叠区间
const result = getOverlapTimeline(array_of_objects[0], array_of_objects[1]);
// 输出的result.timelineA和result.timelineB长度完全一致,下标对应同一个公共日期的数值
console.log(result.timelineA, result.timelineB);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:31:35