如何递归计算层级数组中父节点的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); };
逻辑说明
- 递归处理子节点:先遍历并转换所有子节点,确保子节点的数值已经计算完成
- 汇总子节点数值:遍历转换后的子节点数组,累加
total和available的总和 - 构造当前节点:
- 对于
group类型节点,直接使用子节点的汇总值作为自身的total和available - 对于
category类型节点,优先使用自身定义的total和available,如果没有定义则使用子节点的汇总值
- 对于
- 支持n层级嵌套:递归逻辑会自动处理任意深度的子节点嵌套,确保每一层父节点都能正确汇总所有后代的数值
内容的提问来源于stack exchange,提问作者lrr59
相关产品推荐
相关产品推荐

