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

如何向含reportYear与reportWeek的对象数组补充缺失周数据?

补全缺失周的对象数组方案

嘿,这个需求我之前也碰到过,补全时间序列的缺失数据确实是报表场景里的常见需求。我给你写个JavaScript的实现方案,思路清晰还容易调整,你看看合不合适:

核心思路

  1. 先确定数据的时间范围(最早的周和最晚的周)
  2. 生成这个范围内的所有完整周序列(包括缺失的周)
  3. 把原数据转换成键值对结构,方便快速查找某一周是否存在
  4. 遍历完整序列,补全缺失的周数据,复用原数据的固定属性(比如员工信息)

代码实现

辅助工具函数

先写两个处理日期和周转换的工具函数,确保周数计算符合ISO标准(周一为一周的开始):

// 根据年份和周数,获取该周周一的UTC日期
function getDateOfWeek(year, week) {
  const d = new Date(Date.UTC(year, 0, 1 + (week - 1) * 7));
  const day = d.getUTCDay();
  // 调整到周一(UTC周日是0,所以周日要减6天,其他情况减到周一)
  const diff = day === 0 ? -6 : 1 - day;
  d.setUTCDate(d.getUTCDate() + diff);
  return d;
}

// 根据日期获取对应的ISO年份和周数
function getYearWeek(date) {
  const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  const dayNum = d.getUTCDay() || 7; // 把周日转为7
  d.setUTCDate(d.getUTCDate() + 4 - dayNum); // 转到该周的周四,确保年份正确
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
  const weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
  return {
    reportYear: d.getUTCFullYear(),
    reportWeek: weekNo
  };
}

主补全函数

function fillMissingWeeks(data) {
  if (data.length === 0) return [];

  // 1. 排序并确定时间范围(最早和最晚的周)
  const sortedData = [...data].sort((a, b) => {
    const aKey = a.reportYear * 100 + a.reportWeek;
    const bKey = b.reportYear * 100 + b.reportWeek;
    return aKey - bKey;
  });
  const startWeek = sortedData[0];
  const endWeek = sortedData[sortedData.length - 1];

  // 2. 生成完整的周序列
  const fullWeekList = [];
  let currentDate = getDateOfWeek(startWeek.reportYear, startWeek.reportWeek);
  const endDate = getDateOfWeek(endWeek.reportYear, endWeek.reportWeek);

  while (currentDate <= endDate) {
    fullWeekList.push(getYearWeek(currentDate));
    // 每周加7天,推进到下一周
    currentDate.setUTCDate(currentDate.getUTCDate() + 7);
  }

  // 3. 把原数据转成Map,用`年份-周数`作为键,快速查找
  const existingWeekMap = new Map();
  data.forEach(item => {
    const key = `${item.reportYear}-${item.reportWeek}`;
    existingWeekMap.set(key, {...item}); // 存副本避免修改原数据
  });

  // 4. 补全缺失的周
  const result = fullWeekList.map(yw => {
    const key = `${yw.reportYear}-${yw.reportWeek}`;
    if (existingWeekMap.has(key)) {
      return existingWeekMap.get(key);
    } else {
      // 复用第一个数据项的固定属性,缺失的数值设为0(可根据需求改null/undefined)
      const template = sortedData[0];
      return {
        ...template,
        reportYear: yw.reportYear,
        reportWeek: yw.reportWeek,
        importanceDegree: 0
      };
    }
  });

  return result;
}

多员工场景扩展

如果你的数据包含多个员工,只需要先按employeeCode分组,再对每个员工单独补全:

function fillMissingWeeksByEmployee(data) {
  // 按员工编码分组
  const employeeGroups = {};
  data.forEach(item => {
    const key = item.employeeCode;
    if (!employeeGroups[key]) employeeGroups[key] = [];
    employeeGroups[key].push(item);
  });

  // 对每个员工组补全周数,合并结果
  const finalResult = [];
  Object.values(employeeGroups).forEach(group => {
    finalResult.push(...fillMissingWeeks(group));
  });

  return finalResult;
}

使用示例

// 你的示例输入
const inputData = [
  {"reportYear":2017,"reportWeek":49,"employeeCode":100,"employeeName":"Peter","importanceDegree":182.0},
  {"reportYear":2017,"reportWeek":52,"employeeCode":100,"employeeName":"Peter","importanceDegree":77.0},
  {"reportYear":2018,"reportWeek":2,"employeeCode":100,"employeeName":"Peter","importanceDegree":90.0}
];

// 补全后的数据
const filledData = fillMissingWeeks(inputData);
console.log(filledData);

运行后会得到包含2017周49-52、2018周1-2的完整数据,其中缺失的周(2017周50、51,2018周1)的importanceDegree会被设为0。

注意事项

  • 周定义调整:如果你的业务中周是从周日开始,需要修改辅助函数里的日期调整逻辑。
  • 默认值设置:缺失周的数值字段(比如importanceDegree)可以根据需求改成null、undefined或者其他默认值。
  • 数据验证:如果原数据中存在同一员工同一周的多条数据,建议先做去重处理,避免Map覆盖问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:12:49