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

如何递归计算层级数组中父节点的total与available汇总值?

解决递归树形结构中父节点total/available的汇总计算问题

问题描述

现有层级数组结构如下:

const arr = [
  {
    group: { id: "group1", groupname: "groupname1" },
    categories: [
      {
        id: "cat1",
        categoryName: "category1",
        total: 5,
        available: 2,
        subCategories: []
      },
      {
        id: "cat2",
        categoryName: "category2",
        total: 15,
        available: 12,
        subCategories: [
          {
            id: "cat3",
            categoryName: "category3",
            total: 15,
            available: 12,
            subCategories: []
          }
        ]
      }
    ]
  },
  {
    group: { id: "group2", groupname: "groupname2" },
    categories: [
      {
        id: "cat4",
        categoryName: "category4",
        total: 25,
        available: 22,
        subCategories: []
      },
      {
        id: "cat5",
        categoryName: "category5",
        total: 50,
        available: 25,
        subCategories: []
      }
    ]
  }
];

需要将其转换为包含key、name、children属性的递归树形结构,并且父节点的total和available需要从所有子节点(支持n层级嵌套)的对应值汇总得到,预期结构如下:

[
  {
    "key": "group1",
    "name": "groupname1",
    "total": 20,
    "available": 24,
    "children": [
      {
        "key": "cat1",
        "name": "category1",
        "total": 5,
        "available": 2,
        "children": []
      },
      {
        "key": "cat2",
        "name": "category2",
        "total": 15,
        "available": 12,
        "children": [
          {
            "key": "cat3",
            "name": "category3",
            "total": 15,
            "available": 12,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "key": "group2",
    "name": "groupname2",
    "total": 75,
    "available": 47,
    "children": [
      {
        "key": "cat4",
        "name": "category4",
        "total": 25,
        "available": 22,
        "children": []
      },
      {
        "key": "cat5",
        "name": "category5",
        "total": 50,
        "available": 25,
        "children": []
      }
    ]
  }
]

现有代码已完成结构转换,但无法实现父节点的数值汇总:

const formatter = (data) => {
  const recursiveTree = (item) => {
    if (item.group) {
      const {
        group: { id, groupname, total, available },
        categories
      } = item;
      return {
        key: id,
        name: groupname,
        total: total || 0,
        available: available || 0,
        children: categories?.map(recursiveTree)
      };
    }
    const { id, categoryName, total, available, subCategories } = item;
    return {
      key: id,
      name: categoryName,
      total: total || 0,
      available: available || 0,
      children: subCategories.map(recursiveTree)
    };
  };
  return data.map(recursiveTree);
};

解决方案

修改递归逻辑,先处理子节点再汇总数值,确保父节点能正确累加所有后代节点的total和available:

const formatter = (data) => {
  const recursiveTree = (item) => {
    let children = [];
    let totalSum = 0;
    let availableSum = 0;

    // 先递归处理所有子节点
    if (item.group) {
      children = item.categories?.map(recursiveTree) || [];
    } else {
      children = item.subCategories?.map(recursiveTree) || [];
    }

    // 汇总子节点的total和available
    children.forEach(child => {
      totalSum += child.total;
      availableSum += child.available;
    });

    // 构造当前节点
    if (item.group) {
      const { id, groupname } = item.group;
      return {
        key: id,
        name: groupname,
        // group无自身数值,直接使用子节点汇总值
        total: totalSum,
        available: availableSum,
        children
      };
    } else {
      const { id, categoryName, total, available } = item;
      // category优先使用自身数值,无值时用子节点汇总值
      return {
        key: id,
        name: categoryName,
        total: total ?? totalSum,
        available: available ?? availableSum,
        children
      };
    }
  };

  return data.map(recursiveTree);
};

逻辑说明

  1. 递归处理子节点:先遍历并转换所有子节点,确保子节点的数值已经计算完成
  2. 汇总子节点数值:遍历转换后的子节点数组,累加total和available的总和
  3. 构造当前节点:
    • 对于group类型节点,直接使用子节点的汇总值作为自身的total和available
    • 对于category类型节点,优先使用自身定义的total和available,如果没有定义则使用子节点的汇总值
  4. 支持n层级嵌套:递归逻辑会自动处理任意深度的子节点嵌套,确保每一层父节点都能正确汇总所有后代的数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:44:55