如何用JavaScript高效将对象数组中的JSON对象合并到复杂对象数组
JavaScript高效实现日期按周分组并格式化的方案
需求回顾
你需要将一组带ISO日期的原始数据,转换为按周聚合的结构,每个周对象包含该周内的日期列表,且日期要格式化为date(日期号)、day(星期缩写)、formattedDate(MM/DD(星期))的格式。
实现方案
这里用一次遍历+分组的方式实现,避免多次循环提升效率,核心用Array.reduce()完成分组,同时同步处理日期格式化:
// 假设我们已经获取到原始数据数组(比如接口返回的数据集) const rawData = [ { "date": "2018-03-31T15:00:00.000Z", "value": "Some Value" }, { "date": "2018-04-01T15:00:00.000Z", "value": "Some Value" }, { "date": "2018-04-02T15:00:00.000Z", "value": "Some Value" } // 更多数据... ]; // 工具函数:把ISO日期转换成目标需要的日期结构 const formatDateItem = (isoDate) => { const date = new Date(isoDate); // 注:这里用本地时间处理,若需UTC时间,替换为getUTCMonth/getUTCDate/getUTCDay const month = (date.getMonth() + 1).toString().padStart(2, '0'); const dayNum = date.getDate(); const weekDayShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][date.getDay()]; const formattedDate = `${month}/${dayNum.toString().padStart(2, '0')}(${weekDayShort})`; return { date: dayNum, day: weekDayShort, formattedDate }; }; // 工具函数:生成日期所在周的唯一标识(以周日为一周起始,用本周日的日期字符串做分组key) const getWeekKey = (isoDate) => { const date = new Date(isoDate); const dayOfWeek = date.getDay(); // 计算当前日期到本周日的天数差(周日差0,周一差6,以此类推) const daysToSunday = dayOfWeek === 0 ? 0 : 7 - dayOfWeek; const sunday = new Date(date); sunday.setDate(date.getDate() + daysToSunday); // 返回YYYY-MM-DD格式的周日日期作为分组标识 return sunday.toISOString().split('T')[0]; }; // 核心转换逻辑 const transformData = (data) => { // 第一步:按周分组,一次遍历完成分组+格式化 const weekGroups = data.reduce((groups, item) => { const weekKey = getWeekKey(item.date); const formattedItem = formatDateItem(item.date); if (!groups[weekKey]) { groups[weekKey] = []; } groups[weekKey].push(formattedItem); return groups; }, {}); // 第二步:把分组对象转换成目标数组结构 return Object.values(weekGroups).map(days => ({ week: { days } })); }; // 执行转换并输出结果 const result = transformData(rawData); console.log(result);
关键细节说明
- 高效性:整个转换仅做一次数组遍历(reduce阶段),后续的
Object.values和map都是线性操作,时间复杂度为O(n),处理大数据量也能保持高效。 - 时区适配:代码默认用本地时间处理日期,若需基于UTC时间计算,只需把
getMonth()/getDate()/getDay()替换为getUTCMonth()/getUTCDate()/getUTCDay()。 - 周起始自定义:当前以周日为一周起始,若需改为周一,只需调整
getWeekKey里的逻辑,计算当前日期到本周一的天数差即可。 - 格式兼容性:用
padStart(2, '0')保证月份、日期为两位数字,完全匹配目标格式要求。
输出示例
针对你给出的原始数据,转换后的结果如下:
[ { "week": { "days": [ { "date": 31, "day": "Sat", "formattedDate": "03/31(Sat)" } ] } }, { "week": { "days": [ { "date": 1, "day": "Sun", "formattedDate": "04/01(Sun)" }, { "date": 2, "day": "Mon", "formattedDate": "04/02(Mon)" } ] } } ]
内容的提问来源于stack exchange,提问作者Vikasdeep Singh
相关产品推荐
相关产品推荐

