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

如何在JavaScript中按嵌套对象值分组整理数组?

按嵌套对象多层分组数组的解决方案

给定包含嵌套banner对象的评论数组,需要按banner.lang → banner.format → user的层级分组,把同语言、同格式、同用户的评论归到一起。

你写的代码问题很明确:每次循环都直接给list[comments[i].banner.lang]赋值新数组,完全覆盖了之前的分组结果,根本没做“检查层级是否存在、存在就追加”的操作,所以之前的数据全丢了。

解决方案

用数组的reduce方法来逐步构建嵌套分组结构是最方便的,每一步先检查当前层级是否存在,不存在就初始化,存在就直接追加数据。

先搞一个更实用的嵌套对象结构(后续访问、操作都方便)

const groupedComments = comments.reduce((acc, comment) => {
  // 拆出分组要用的字段
  const { lang, format } = comment.banner;
  const { user } = comment;
  // 提取评论的核心数据
  const commentData = {
    id: comment.id,
    bannerId: comment.bannerId,
    comment: comment.content
  };

  // 初始化语言层,不存在就建空对象
  if (!acc[lang]) {
    acc[lang] = {};
  }
  // 初始化格式层
  if (!acc[lang][format]) {
    acc[lang][format] = {};
  }
  // 初始化用户层,已存在就直接加评论
  if (!acc[lang][format][user]) {
    acc[lang][format][user] = [];
  }
  acc[lang][format][user].push(commentData);

  return acc;
}, {});

输出的结构是这样的,比你期望的数组结构更易访问:

{
  "EN": {
    "300x250": {
      "John Doe": [
        {"id": 1745, "bannerId": 35002, "comment": "lorem ipsum"},
        {"id": 1747, "bannerId": 35002, "comment": "test 2222"}
      ],
      "Frank Doe": [
        {"id": 1750, "bannerId": 35002, "comment": "test 3333"}
      ]
    },
    "300x600": {
      "John Doe": [
        {"id": 1744, "bannerId": 35004, "comment": "bla bla"}
      ]
    }
  },
  "NL": {
    "970x250": {
      "Frank Doe": [
        {"id": 1746, "bannerId": 35006, "comment": "tesssttt"}
      ]
    }
  }
}

转换成你想要的数组包裹结构

如果一定要和你期望的结构完全一致,在上面的结果基础上做个格式转换就行:

const formattedResult = Object.entries(groupedComments).map(([lang, formats]) => {
  return {
    [lang]: Object.entries(formats).map(([format, users]) => {
      return {
        [format]: Object.entries(users).map(([user, comments]) => {
          return { [user]: comments };
        })
      };
    })
  };
});

输出结果就和你给出的期望结构一模一样了。

关键逻辑说明

  1. reduce是用来累积结果的,每次遍历都往已有的结构里加数据,不会像你原来的代码那样直接覆盖
  2. 每一层级都先判断是否存在,不存在就初始化对应的对象或数组,确保不会出现undefined的情况
  3. 用Object.entries把对象的键值对转成数组,再通过map逐层转换成你要的数组包裹格式

内容的提问来源于stack exchange,提问作者Slicer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:51:24