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

如何在JavaScript中高效将扁平数组转为带children的树形结构?

JavaScript 高效实现扁平数组转层级化children数组

需求说明

将扁平对象数组按type、lastname层级分组,父节点的age为子节点age总和,生成带children属性的层级数组。

源数据格式

const arrayObjects = [
  { name: "Alice", lastname: "Silva", age: 25, type: "A", city: "São Paulo" },
  { name: "Bruno", lastname: "Pereira", age: 30, type: "A", city: "Belo Horizonte" },
  { name: "Camila", lastname: "Silva", age: 35, type: "B", city: "São Paulo" },
  { name: "Daniel", lastname: "Pereira", age: 40, type: "B", city: "Belo Horizonte" },
  { name: "Eduardo", lastname: "Silva", age: 45, type: "B", city: "Belo Horizonte" },
  { name: "Fernanda", lastname: "Silva", age: 50, type: "A", city: "São Paulo" },
];

期望输出格式

const arrayOutPut = [
  {
    age: 105,
    type: "A",
    children: [
      {
        age: 75,
        type: "A",
        lastname: "Silva",
        children: [
          { name: "Alice", lastname: "Silva", age: 25, type: "A", city: "São Paulo" },
          { name: "Fernanda", lastname: "Silva", age: 50, type: "A", city: "São Paulo" }
        ]
      },
      {
        age: 30,
        type: "A",
        lastname: "Pereira",
        children: [
          { name: "Bruno", lastname: "Pereira", age: 30, type: "A", city: "Belo Horizonte" }
        ]
      }
    ]
  }
]

高效实现方案

核心思路是用reduce完成分层分组,再基于分组结果构建层级结构并计算age总和,全程仅需遍历源数组一次,性能高效。

function transformFlatArray(arr) {
  // 按 type -> lastname 两层分组
  const grouped = arr.reduce((acc, item) => {
    if (!acc[item.type]) acc[item.type] = {};
    if (!acc[item.type][item.lastname]) acc[item.type][item.lastname] = [];
    acc[item.type][item.lastname].push(item);
    return acc;
  }, {});

  // 构建最终层级数组
  return Object.entries(grouped)
    // 若需过滤特定type,添加此行:.filter(([type]) => type === "A")
    .map(([type, lastnameGroups]) => {
      const children = Object.entries(lastnameGroups).map(([lastname, items]) => ({
        age: items.reduce((sum, item) => sum + item.age, 0),
        type,
        lastname,
        children: [...items]
      }));

      return {
        age: children.reduce((sum, child) => sum + child.age, 0),
        type,
        children
      };
    });
}

// 调用示例
const result = transformFlatArray(arrayObjects);
console.log(result);

代码说明

  • 分组阶段:通过一次reduce遍历,将元素按type和lastname嵌套分组,把同类型同姓氏的元素归入同一集合。
  • 层级构建:
    • 遍历每个type分组,为每个lastname组生成子节点,子节点的age是组内元素的年龄总和,children为组内原始元素。
    • 计算每个type节点的总年龄(所有子节点年龄之和),生成顶层节点。
  • 性能优势:时间复杂度为O(n)(n为源数组长度),仅需一次遍历源数组,后续操作均为线性处理,是高效的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:35:14