如何对嵌套数据结构数组按日期类键升序排序?
嵌套日期分组数组的排序实现方案
需求说明
- 父数组中的「月份对象」(键格式如
"2022/11")按日期键升序排序; - 月份对象内的「日期对象」(键格式如
"2022/11/30")按日期键升序排序。
输入数组
const grouped = [ { "2022/11": [ { "2022/11/30": [ { "breaking-change": [ { date: "2022-11-30T07:33:07.992955008Z", reponame: "test-repo", status: "breaking-change", }, ], }, ], }, { "2022/11/29": [ { compatible: [ { date: "2022-11-29T14:58:44+01:00", reponame: "test-repo", status: "compatible", }, ], }, ], }, ], }, { "2022/10": [ { "2022/10/17": [ { compatible: [ { date: "2022-10-17T14:58:44+01:00", reponame: "test-repo", status: "compatible", }, ], }, ], }, ], }, ];
期望输出数组
[ { "2022/10": [ { "2022/10/17": [ { compatible: [ { date: "2022-10-17T14:58:44+01:00", reponame: "test-repo", status: "compatible", }, ], }, ], }, ], }, { "2022/11": [ { "2022/11/29": [ { compatible: [ { date: "2022-12-17T14:58:44+01:00", reponame: "test-repo", status: "compatible", }, ], }, ], }, { "2022/11/30": [ { "breaking-change": [ { date: "2022-11-30T07:33:07.992955008Z", reponame: "test-repo", status: "breaking-change", }, ], }, ], }, ], }, ];
已尝试的代码及问题
- 仅完成父级排序的代码:
const sortedGrouped = grouped.sort(function (a, b) { return ( new Date(Object.keys(a)[0]).getTime() - new Date(Object.keys(b)[0]).getTime() ); });
- 问题:仅能对最外层月份对象排序,无法处理内部日期对象的排序需求。
- 出现语法错误的代码:
grouped.forEach((obj) => { Object.values(obj) = Object.values(obj).sort(function (a, b) { return ( new Date(Object.keys(a)[0]).getTime() - new Date(Object.keys(b)[0]).getTime() ); }); });
- 问题:
Object.values(obj)不能作为赋值语句的左值,触发Invalid left-hand side in assignment expression语法错误。
- 无法正常工作的代码:
const sortByDate = arr => { const sorter = (a, b) => { return new Date(Object.keys(a)[0]).getTime() - new Date(Object.keys(b)[0]).getTime(); }; arr.forEach((i)=>Object.values(i).sort(sorter)) return arr; };
- 问题:
Object.values(i).sort(sorter)返回排序后的数组,但未将结果重新赋值回原对象的对应属性,原数组结构不会被修改。
正确实现方案
我们需要先对最外层月份数组排序,再遍历每个月份对象,取出内部日期数组排序后重新赋值。代码如下:
// 通用日期键比较函数,复用排序逻辑 const compareDateKeys = (a, b) => { const dateA = new Date(Object.keys(a)[0]); const dateB = new Date(Object.keys(b)[0]); return dateA.getTime() - dateB.getTime(); }; // 1. 对最外层月份对象数组排序(浅拷贝原数组避免直接修改) const sortedGrouped = [...grouped].sort(compareDateKeys); // 2. 遍历每个月份对象,对内部日期数组排序并赋值 sortedGrouped.forEach(monthObj => { const [monthKey] = Object.keys(monthObj); const dateArr = monthObj[monthKey]; monthObj[monthKey] = dateArr.sort(compareDateKeys); }); console.log(sortedGrouped);
代码说明
[...grouped]创建原数组的浅拷贝,若无需保留原数组可直接使用grouped.sort(compareDateKeys);compareDateKeys函数统一处理日期键的比较逻辑,减少代码冗余;- 遍历月份对象时,通过
Object.keys(monthObj)[0]获取唯一月份键,取出对应日期数组排序后重新赋值,确保修改生效。
内容的提问来源于stack exchange,提问作者AlexUA
相关产品推荐
相关产品推荐

