按年份和月份分组JavaScript数组求助(含Lodash尝试)
按年份+月份层级分组JavaScript数组的解决方案
问题背景
现有如下结构的JavaScript数组:
const myArray = [ { "_id": "0c35e243", "createdDate": "2021-05-19T08:58:14.497Z", "description": "desc text", }, { "_id": "08e05fcb", "createdDate": "2022-07-19T08:42:34.702Z", "desc": "desc text2", }, { "_id": "6a33dca3", "createdDate": "2021-07-19T08:35:53.199Z", "desc": "desc text3", }, { "_id": "58ea808d", "createdDate": "2022-08-19T08:13:35.516Z", "desc": "desc text4", }, { "_id": "a95b706c", "createdDate": "2022-08-19T04:12:44.941Z", "desc": "desc text5", }, ];
需要将其按年份→月份的层级分组,优先使用月份名称(如May、July)而非数字,预期结果为嵌套对象结构:
{ "2022": { "July": [ { "_id": "08e05fcb", "createdDate": "2022-07-19T08:42:34.702Z", "desc": "desc text2", } ], "August": [ { "_id": "58ea808d", "createdDate": "2022-08-19T08:13:35.516Z", "desc": "desc text4", }, { "_id": "a95b706c", "createdDate": "2022-08-19T04:12:44.941Z", "desc": "desc text5", }, ] }, "2021": { "May": [ { "_id": "0c35e243", "createdDate": "2021-05-19T08:58:14.497Z", "description": "desc text", } ], "July": [ { "_id": "6a33dca3", "createdDate": "2021-07-19T08:35:53.199Z", "desc": "desc text3", } ] } }
此前尝试用Lodash的groupBy按月份分组成功,但二次按年份分组时返回NaN,原因是第二次分组时传入的是已分组的对象(键为月份数字,值为元素数组),回调函数错误地试图从数组中提取日期属性,导致逻辑失效。
解决方案
方案一:原生JavaScript实现(无需第三方库)
利用数组的reduce方法遍历元素,逐步构建嵌套分组结构:
// 定义月份名称数组,对应getMonth()返回的0-11索引 const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; const groupedResult = myArray.reduce((acc, item) => { const date = new Date(item.createdDate); const year = date.getFullYear().toString(); const month = monthNames[date.getMonth()]; // 初始化年份层级 if (!acc[year]) { acc[year] = {}; } // 初始化月份层级 if (!acc[year][month]) { acc[year][month] = []; } // 将当前元素加入对应分组 acc[year][month].push(item); return acc; }, {});
方案二:Lodash实现
通过两次groupBy结合mapValues实现层级分组:
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; const groupedResult = _.mapValues( // 第一步:按年份分组 _.groupBy(myArray, item => new Date(item.createdDate).getFullYear()), // 第二步:对每个年份组内的元素按月份名称分组 yearGroup => _.groupBy(yearGroup, item => monthNames[new Date(item.createdDate).getMonth()]) );
内容的提问来源于stack exchange,提问作者etcN00b
相关产品推荐
相关产品推荐

