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

JavaScript中按时间累加两个有序对象数组值的高效实现方案

解决两个时序数组的缺失日期累加问题

这问题确实很典型——两个按时间排序的数组,要处理日期不匹配时用最近值补全求和,你最初的思路方向是对的,但只覆盖了"长数组有、短数组无"的情况,没考虑反过来的场景。其实利用两个数组已排序的特性,用双指针法就能在一次遍历里搞定所有情况,时间复杂度是O(n+m),非常高效。

核心思路

既然两个数组都是按日期升序排列的,我们可以用两个指针分别跟踪两个数组的当前位置,同时记录各自的"最近已知值"。每次比较两个指针指向的日期,优先处理更早的那个日期:

  • 如果A数组的日期更早:用B数组的最近值和A的当前值相加,加入结果,然后移动A的指针,更新A的最近值。
  • 如果B数组的日期更早:用A数组的最近值和B的当前值相加,加入结果,然后移动B的指针,更新B的最近值。
  • 如果日期相同:直接相加两个值,加入结果,同时移动两个指针,更新各自的最近值。
  • 当其中一个数组遍历完后,处理另一个数组剩下的元素,用对应的最近值补全求和。

代码实现

function mergeAndSum(data1, data2) {
    let i = 0, j = 0;
    const result = [];
    // 初始化最近值,处理数组为空的边界情况(如果数组为空,最近值设为0)
    let lastVal1 = data1.length > 0 ? data1[0].value : 0;
    let lastVal2 = data2.length > 0 ? data2[0].value : 0;

    // 辅助函数:将日期字符串转为Date对象,方便比较
    const parseDate = (dateStr) => {
        const [day, month, year] = dateStr.split('-');
        return new Date(year, month - 1, day); // 注意月份是0-based
    };

    while (i < data1.length || j < data2.length) {
        // 获取当前指针的日期(如果指针越界,设为极大值,确保不会被优先处理)
        const date1 = i < data1.length ? parseDate(data1[i].date) : new Date(Infinity);
        const date2 = j < data2.length ? parseDate(data2[j].date) : new Date(Infinity);

        if (date1 < date2) {
            // data1的日期更早,用data2的最近值相加
            result.push({
                date: data1[i].date,
                value: data1[i].value + lastVal2
            });
            lastVal1 = data1[i].value; // 更新data1的最近值
            i++;
        } else if (date2 < date1) {
            // data2的日期更早,用data1的最近值相加
            result.push({
                date: data2[j].date,
                value: data2[j].value + lastVal1
            });
            lastVal2 = data2[j].value; // 更新data2的最近值
            j++;
        } else {
            // 日期相同,直接相加
            result.push({
                date: data1[i].date,
                value: data1[i].value + data2[j].value
            });
            lastVal1 = data1[i].value;
            lastVal2 = data2[j].value;
            i++;
            j++;
        }
    }

    return result;
}

// 测试你的示例数据
const data1 = [ {date: "30-08-2019", value: 1}, {date: "03-09-2019", value: 2}, {date: "04-09-2019", value: 3} ];
const data2 = [ {date: "30-08-2019", value: 1}, {date: "02-09-2019", value: 2}, {date: "03-09-2019", value: 3}, {date: "04-09-2019", value: 4} ];

console.log(mergeAndSum(data1, data2));
// 输出结果和你期望的完全一致:
// [
//   { date: '30-08-2019', value: 2 },
//   { date: '02-09-2019', value: 3 },
//   { date: '03-09-2019', value: 5 },
//   { date: '04-09-2019', value: 7 }
// ]

为什么这个方案更好?

  • 全覆盖:不管哪个数组有额外的日期,都能被正确处理,不会遗漏任何元素。
  • 高效:只需要一次遍历两个数组,时间复杂度O(n+m),比先补全数组再求和的方法高效得多。
  • 鲁棒性:处理了数组为空的边界情况,避免报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:47:29