如何用LoDash按ISO周分组时间序列数据并汇总注册量?
用Lodash按ISO周分组汇总注册量的正确实现
我来帮你搞定这个问题!按ISO周分组汇总注册量用Lodash其实不难,关键是要准确生成符合ISO标准的周标识,再配合Lodash的分组和汇总方法。下面是具体的实现步骤和代码示例:
首先明确ISO周规则
ISO周的核心规则是:
- 每周从周一开始,周日结束
- 一年的第一周必须包含当年的1月4日(也就是至少有4天在当年),所以跨年的日期可能属于上一年或下一年的周(比如2023年12月31日属于2024年的第1周)
第一步:实现ISO周标识生成函数
JavaScript原生Date对象没有直接获取ISO周的方法,我们需要自己写一个函数把日期字符串转换成YYYY-Www格式的ISO周标识(比如2024-W01):
function getISOWeekKey(dateStr) { const date = new Date(dateStr); // 转换为UTC时间避免时区问题 const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); // 把周日转为7(ISO周中周一为1,周日为7) const dayOfWeek = utcDate.getUTCDay() || 7; // 调整日期到本周的周四(ISO周的基准日,用来确定所属年份) utcDate.setUTCDate(utcDate.getUTCDate() + 4 - dayOfWeek); const isoYear = utcDate.getUTCFullYear(); // 计算当年第一天到基准日的天数,进而得到周数 const yearStart = new Date(Date.UTC(isoYear, 0, 1)); const daysSinceYearStart = Math.floor((utcDate - yearStart) / 86400000); const isoWeek = Math.ceil((daysSinceYearStart + 1) / 7); // 格式化为两位周数的字符串 return `${isoYear}-W${String(isoWeek).padStart(2, '0')}`; }
第二步:用Lodash分组并汇总注册量
这里提供两种常用的实现方式:
方式1:用_.reduce一步完成分组+汇总
这种方式效率更高,只需要遍历一次数据:
const _ = require('lodash'); // 示例数据(模拟你的注册数据) const registrationData = [ { date: '2023-12-31', registrations: 3 }, { date: '2024-01-01', registrations: 10 }, { date: '2024-01-02', registrations: 5 }, { date: '2024-01-08', registrations: 8 }, { date: '2024-01-15', registrations: 12 }, ]; const result = _.reduce(registrationData, (acc, item) => { const weekKey = getISOWeekKey(item.date); // 如果当前周不存在,初始化为0,再累加注册量 acc[weekKey] = (acc[weekKey] || 0) + item.registrations; return acc; }, {}); console.log(result); // 输出:{ '2024-W01': 18, '2024-W02': 8, '2024-W03': 12 }
方式2:先_.groupBy分组,再_.mapValues汇总
这种方式更直观,适合需要先保留分组后的原始数据的场景:
// 先按ISO周分组 const groupedData = _.groupBy(registrationData, item => getISOWeekKey(item.date)); // 对每组的注册量求和 const summedResult = _.mapValues(groupedData, group => _.sumBy(group, 'registrations')); console.log(summedResult); // 输出和上面一致
你之前方案出错的常见原因
大概率是这两个问题:
- ISO周计算错误:比如用了周日作为一周的第一天,或者没有处理跨年的周归属(比如把2023-12-31算成2023年的最后一周,但实际上它属于2024年第1周)
- 汇总逻辑错误:只做了分组(
_.groupBy)但没有对每组的注册量求和,直接返回了分组后的数组,而不是汇总后的数值
内容的提问来源于stack exchange,提问作者Hedge
相关产品推荐
相关产品推荐

