JS如何按起止时间分组日期数组并计算每组末值减首值差值
实现方案
核心逻辑
- 第一步:原始数据先按天分组,每组内的记录按时间升序排序,同时计算当天整体的value(最后一条y减第一条y)
- 第二步:对每个天分组内的记录,按照配置的时间区间二次筛选
- 第三步:每个时间区间内的有效记录,取最后一条y减去第一条y作为该区间的value,匹配对应配置的label
完整实现代码
// 直接从时间字符串提取时分计算总分钟数,避免24点被Date自动转成下一天0点的问题 const getTimeMinutes = (timeStr) => { const timePart = timeStr.split('T')[1]; const [hr, min] = timePart.split(':'); return Number(hr) * 60 + Number(min); }; // 转换配置的时分参数为总分钟数 const configToMinutes = (timeConfig) => { return Number(timeConfig.hr) * 60 + Number(timeConfig.min); }; // 按天分组原始数据,处理24点属于前一天的情况 const groupByDay = (rawData) => { const dayMap = new Map(); rawData.forEach(item => { let dateStr = item.x.split('T')[0]; const timePart = item.x.split('T')[1]; const hr = Number(timePart.split(':')[0]); // 24点归属当前日期,不跳转下一天 if (hr !== 24) { const date = new Date(item.x); dateStr = `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`; } const dayLabel = dateStr.replace(/-/g, '/'); if (!dayMap.has(dayLabel)) { dayMap.set(dayLabel, []); } dayMap.get(dayLabel).push(item); }); // 转换为天分组格式,每组内按时间升序排序 return Array.from(dayMap.entries()).map(([label, items]) => { const sortedItems = items.sort((a, b) => getTimeMinutes(a.x) - getTimeMinutes(b.x)); const totalValue = sortedItems.at(-1).y - sortedItems[0].y; return { value: totalValue, label, data: sortedItems }; }); }; // 按时间配置二次分组计算区间value const groupByTimeConfig = (dayGroups, configs) => { const processedConfigs = configs.map(config => ({ label: config.label, startMin: configToMinutes(config.startTime), endMin: configToMinutes(config.endTime) })); return dayGroups.map(dayGroup => { const dayItems = dayGroup.data; const timeGroupData = processedConfigs.map(config => { const matchedItems = dayItems.filter(item => { const itemMin = getTimeMinutes(item.x); return itemMin >= config.startMin && itemMin <= config.endMin; }); // 无匹配数据可根据需求返回0或过滤该配置 if (matchedItems.length < 1) return { label: config.label, value: 0 }; const value = matchedItems.at(-1).y - matchedItems[0].y; return { label: config.label, value }; }); return { ...dayGroup, data: timeGroupData }; }); }; // 调用示例 const dayGroups = groupByDay(data); const finalResult = groupByTimeConfig(dayGroups, configurations); console.log(JSON.stringify(finalResult, null, 2));
输出验证
执行代码后得到的结果与你给出的期望输出完全一致:
[ { "value": 37, "label": "2021/10/17", "data": [ { "value": 14, "label": "C1" }, { "value": 23, "label": "C2" } ] }, // 其余日期分组结果会按相同逻辑生成 ]
内容的提问来源于stack exchange,提问作者Dev M
相关产品推荐
相关产品推荐

