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

JavaScript中为对象数组的嵌套数组补充缺失日期对象

问题需求

处理后端返回的对象数组,将每个对象中嵌套的hours数组内的日期与指定日期数组compDates比对,若hours中不存在对应日期,则添加count: 0的对象。

原始数据

[{
  _id: "6205a8313fe12d6b4ec354c4",
  fullName: "Johnny Cochrane",
  contracts: {
    type: "Quarterly",
    hours: 120,
  },
  client: "6205a8313fe12d6b4ec354c4",
  hours: [{
    date: "2023-5",
    count: 6,
  }, {
    date: "2023-6",
    count: 2,
  }],
}, {
  _id: "6217c1b73fe12d6b4ec3550e",
  fullName: "Sheila Thompson",
  contracts: {
    type: "Quarterly",
    hours: 140,
  },
  client: "6217c1b73fe12d6b4ec3550e",
  hours: [{
    date: "2023-4",
    count: 5.5,
  }, {
    date: "2023-6",
    count: 2,
  }],
}]

生成对比日期的代码

const qtrs = [{qtr: 1, mths: [1,2,3]}, {qtr: 2, mths: [4,5,6]}, {qtr: 3, mths: [7,8,9]}, {qtr: 4, mths: [10,11,12]} ]

const currentMth = new Date().getMonth() + 1

const currentQtr = qtrs.filter(({mths}) => mths.includes(currentMth))

const compDates = currentQtr[0].mths.map(i => new Date(new Date(new Date().setMonth(i)).setHours(0, 0, 0, 0)).toISOString())

尝试过的处理代码

const adjust = data.forEach(i => {
  i.hours.forEach(item => {
  console.log("item1: ",item)
  const interim = new Date(item.date).getMonth() + 1
  console.log(interim)
  item.date =  new Date(new Date(new Date().setMonth(interim)).setHours(0, 0, 0, 0)).toISOString()
  console.log(item.date)

//Steps I've tried- 1st:
cursor = 0
Object.entries(item).map(obj => {console.log(obj); compDates[cursor] && compDates[cursor] == obj.date ? {...obj} :{count: 0, date: obj.date, total: obj.total}});

//2nd try
Object.values(item).map(x => (compDates.find(y => y === x.date) ? {...x}: {count: 0, date: x.date, total: x.total}))

//3rd
if (compDates.find(y => y === item.date)) {
    item = item
  } else {
   item = {count: 0, date: item.date, total: item.total}
  } 


})})

期望输出

对比日期示例

["2023-05-16T07:00:00.258Z", "2023-06-16T07:00:00.258Z", "2023-07-16T07:00:00.258Z"]

处理后的数据

[{
  _id: "6205a8313fe12d6b4ec354c4",
  fullName: "Johnny Cochrane",
  contracts: {
    type: "Quarterly",
    hours: 120,
  },
  client: "6205a8313fe12d6b4ec354c4",
  hours: [{
    date: "2023-4", // 比对阶段无需改回ISO日期格式
    count: 0,
  }, {
    date: "2023-5",
    count: 6,
  }, {
    date: "2023-6",
    count: 2,
  }],
}, {
  _id: "6217c1b73fe12d6b4ec3550e",
  fullName: "Sheila Thompson",
  contracts: {
    type: "Quarterly",
    hours: 140,
  },
  client: "6217c1b73fe12d6b4ec3550e",
  hours: [{
    date: "2023-4",
    count: 5.5,
  }, {
    date: "2023-5", // 同样无需改回原格式
    count: 0,
  }, {
    date: "2023-6",
    count: 2,
  }],
}]

解决方案

你之前的尝试只在修改原有hours项,没遍历compDates补全缺失项,而且原compDates生成逻辑有问题(重复修改同一个Date对象导致日期错误)。以下是可行的处理方案:

修复并优化的代码

// 修复compDates生成逻辑,避免日期对象污染
const qtrs = [{qtr: 1, mths: [1,2,3]}, {qtr: 2, mths: [4,5,6]}, {qtr: 3, mths: [7,8,9]}, {qtr: 4, mths: [10,11,12]} ]
const currentYear = new Date().getFullYear();
const currentMth = new Date().getMonth() + 1;
const currentQtr = qtrs.find(({mths}) => mths.includes(currentMth)); // 用find更高效,仅返回匹配的季度

// 生成每个季度月份的当月第一天ISO格式日期
const compDates = currentQtr.mths.map(month => {
  const date = new Date(currentYear, month - 1, 1); // 月份从0开始,需减1
  date.setHours(0, 0, 0, 0);
  return date.toISOString();
});

// 处理数据的核心函数
const processData = (data) => {
  return data.map(person => {
    // 把已有hours转成Map,key为ISO日期,value为count,方便快速查找
    const existingHoursMap = new Map(
      person.hours.map(item => {
        // 将原始"YYYY-M"格式转成ISO格式
        const [year, month] = item.date.split('-');
        const date = new Date(parseInt(year), parseInt(month) - 1, 1);
        date.setHours(0, 0, 0, 0);
        return [date.toISOString(), item.count];
      })
    );

    // 遍历compDates生成完整的hours数组,缺失的日期补count:0
    const updatedHours = compDates.map(date => ({
      // 若需要转回"YYYY-M"格式,替换下面的date字段:
      // date: `${new Date(date).getFullYear()}-${new Date(date).getMonth() + 1}`,
      date: date,
      count: existingHoursMap.get(date) || 0
    }));

    return {
      ...person,
      hours: updatedHours
    };
  });
};

// 使用示例:传入你的原始数据
const processedResult = processData(原始数据);
console.log(processedResult);

代码说明

  1. 修复日期生成逻辑:原代码多次调用setMonth会修改同一个Date对象,导致后续月份计算错误,改用创建新Date对象的方式生成正确的对比日期;
  2. 用Map优化查找效率:将已有日期和count存入Map,比对时时间复杂度从O(n)降到O(1);
  3. 补全缺失日期:直接遍历compDates生成完整的hours数组,确保每个对比日期都存在,缺失项自动补count:0;
  4. 格式灵活切换:保留了日期格式转换的选项,可根据需求选择ISO格式或原始的"YYYY-M"格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:37:11