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

JavaScript按工作日+半小时区间聚合handled值异常问题

问题分析与解决方案:按工作日+半小时区间聚合数据

首先,你的核心问题有两个:所有工作日共享了同一个intervalObj引用,以及冗余的循环逻辑导致不必要的遍历。我们一步步来解决:

1. 根本问题:对象引用共享导致批量修改

你最初创建intervalObj后,直接把它赋值给每个工作日的data属性:

for (i = 1; i <= 5; i++) { hhObj.push({ day: i, data: intervalObj }) }

在JavaScript中,数组是引用类型,这意味着所有工作日的data都指向同一个内存地址的数组。所以你修改任意一个工作日的区间数据时,其他所有工作日的对应数据都会跟着改变——这就是为什么所有工作日的相同区间会出现重复的求和结果。

解决方法:为每个工作日创建独立的区间数组副本

我们需要给每个工作日生成一个intervalObj的独立副本,确保它们互不影响:

// 固定的半小时区间数组
const halfHours = ["00:00", "00:30", "01:00", "01:30", "02:00", "02:30", "03:00", "03:30", "04:00", "04:30", "05:00", "05:30", "06:00", "06:30", "07:00", "07:30", "08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30", "18:00", "18:30", "19:00", "19:30", "20:00", "20:30", "21:00", "21:30", "22:00", "22:30", "23:00", "23:30"];

// 创建基础区间模板
const intervalObj = halfHours.map(interval => ({
  interval: interval,
  answered: 0,
  handled: 0
}));

// 为每个工作日创建独立的区间数组
const hhObj = [];
for (let i = 1; i <= 5; i++) {
  // 使用展开运算符浅拷贝模板数组(因为数组项都是基本类型,浅拷贝足够)
  const dayIntervalData = intervalObj.map(item => ({...item}));
  hhObj.push({ day: i, data: dayIntervalData });
}

2. 优化循环逻辑:减少冗余遍历

你原来的内层循环遍历了所有5个工作日,这完全没必要——我们可以直接根据当前数据的工作日,定位到hhObj中对应的对象,再找到匹配的区间进行累加。

另外注意:Date.getDay()返回的是0(周日)到6(周六),而你的hhObj是1-5对应周一到周五,所以需要过滤掉周日和周六的数据。同时,半小时区间的判断可以更严谨(比如把0-29分归到00区间,30-59分归到30区间)。

修正后的数据聚合逻辑

const test = [
  {"DateTime":"5/1/18 03:00:00 AM","Answered":"0","handled":"3"},
  {"DateTime":"5/3/18 10:00:00 AM","Answered":"0","handled":"1"},
  {"DateTime":"5/2/18 07:00:00 AM","Answered":"0","handled":"25"},
  {"DateTime":"5/5/18 12:00:00 AM","Answered":"0","handled":"2"},
  {"DateTime":"5/10/18 12:00:00 AM","Answered":"0","handled":"6"},
  {"DateTime":"5/12/18 07:00:00 AM","Answered":"0","handled":"1"},
  {"DateTime":"5/13/18 12:00:00 AM","Answered":"0","handled":"12"},
  {"DateTime":"5/1/18 07:00:00 AM","Answered":"0","handled":"5"},
  {"DateTime":"5/6/18 10:00:00 AM","Answered":"0","handled":"1"},
  {"DateTime":"5/7/18 12:00:00 AM","Answered":"0","handled":"2"},
  {"DateTime":"5/3/18 12:00:00 AM","Answered":"0","handled":"0"},
  {"DateTime":"5/18/18 06:00:00 AM","Answered":"0","handled":"14"},
  {"DateTime":"5/12/18 12:30:00 AM","Answered":"0","handled":"1"}
];

for (const row of test) {
  const dt = new Date(row.DateTime);
  const weekDay = dt.getDay();
  
  // 只处理周一到周五(weekDay 1-5),跳过周日(0)和周六(6)
  if (weekDay < 1 || weekDay > 5) continue;

  // 计算对应的半小时区间
  let hh = dt.getHours();
  if (hh < 10) hh = `0${hh}`;
  const mm = dt.getMinutes() < 30 ? '00' : '30';
  const timeInterval = `${hh}:${mm}`;

  const handled = parseInt(row.handled, 10);
  if (isNaN(handled)) continue; // 跳过无效数值

  // 定位到当前工作日的data数组
  const dayIdx = weekDay - 1; // day1对应索引0,day5对应索引4
  const targetDayData = hhObj[dayIdx].data;
  
  // 找到匹配的区间并累加handled值
  const targetInterval = targetDayData.find(item => item.interval === timeInterval);
  if (targetInterval) {
    targetInterval.handled += handled;
  }
}

最终效果

修正后,每个工作日的data数组都是独立的,累加操作只会影响对应工作日的对应区间,不会出现所有工作日重复相同结果的问题,完全符合你的预期结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:49:47