You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按年份和月份分组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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:58:06