如何在 Node.js 中按公共字段合并多个数组中的数据

12次阅读

如何在 Node.js 中按公共字段合并多个数组中的数据

本文介绍如何将嵌套的二维用户数据数组,按 `class_id` 字段归并为统一结构:每个班级对应一个对象,其 `students` 数组包含该班所有学生(仅保留 `roll_number` 和 `name`)。核心方法是先扁平化再用 `reduce` 构建哈希映射,最后提取值。

node.js(或现代浏览器环境)中处理多维嵌套数据时,直接使用 mapfor 循环逐层遍历容易遗漏跨子数组的同字段聚合逻辑——正如提问中所示:原始数据是二维数组(每个子数组可能含多个不同 class_id 的学生),而需求是按 class_id 全局分组,而非按子数组顺序分组。

✅ 正确思路:扁平化 + 累积映射 + 提取值

  1. flat() 扁平化:将二维数组转为一维,消除嵌套层级干扰;
  2. reduce() 构建索引对象:以 class_id 为键,动态初始化班级对象 { class_id, students: [] };
  3. Object.values() 提取结果:将键值对映射转为符合要求的数组格式。

以下是完整、可直接运行的解决方案:

const data = [   [     { class_id: "Grade 1", roll_number: "1", name: "alex" },     { class_id: "Grade 1", roll_number: "2", name: "bob" },   ],   [     { class_id: "Grade 2", roll_number: "7", name: "peter" },     { class_id: "Grade 3", roll_number: "6", name: "lia" },     { class_id: "Grade 2", roll_number: "5", name: "mary" },     { class_id: "Grade 3", roll_number: "1", name: "violet" },   ], ];  const result = data   .flat() // → [{...}, {...}, {...}, ...]   .reduce((acc, { class_id, roll_number, name }) => {     // 若该 class_id 尚未存在,则初始化     acc[class_id] ??= { class_id, students: [] };     // 向对应班级的 students 数组推入精简学生对象     acc[class_id].students.push({ roll_number, name });     return acc;   }, {});  console.log(Object.values(result)); // 输出: // [ //   { class_id: "Grade 1", students: [{ roll_number: "1", name: "alex" }, { roll_number: "2", name: "bob" }] }, //   { class_id: "Grade 2", students: [{ roll_number: "7", name: "peter" }, { roll_number: "5", name: "mary" }] }, //   { class_id: "Grade 3", students: [{ roll_number: "6", name: "lia" }, { roll_number: "1", name: "violet" }] } // ]

⚠️ 注意事项

  • 兼容性Array.prototype.flat() 和 ??=(Nullish Coalescing Assignment)需 Node.js ≥ 12(推荐 ≥ 14.17+)或现代浏览器支持。若需兼容旧环境,可用 [].concat(…data) 替代 flat(),用 acc[class_id] = acc[class_id] || { class_id, students: [] } 替代 ??=。
  • 字段健壮性:代码假设每条记录必含 class_id、roll_number、name。生产环境中建议增加校验(如 if (!class_id) continue;)。
  • 性能:该方案时间复杂度为 O(n),空间复杂度为 O(k),其中 n 是总学生数,k 是唯一班级数,高效且易于维护。

此模式不仅适用于学籍管理,也广泛用于日志聚合、订单分组、API 多请求结果合并等场景——关键在于用对象作临时索引容器,避免手动维护索引位置或重复查找

text=ZqhQzanResources