如何在JavaScript中递归遍历对象并按层级计算各节点总和?
问题描述
给定嵌套对象:
{ "a":{ "a1":5, "b":{ "b1":10, "b2":15, "c":{ "c1":15 } } } }
期望输出:
{a:45, b:40, c: 15}
计算逻辑(对应期望输出):
c:自身数值属性之和,即15b:自身数值属性之和(10+15)加上c的计算结果,即25+15=40a:自身数值属性之和(5)加上b的计算结果,即5+40=45
用户尝试的代码:
let constructedTotals = {}; const calculateVals = (vals) => { return vals .map((val) => { if (typeof val === "object" && Object.keys(val).length > 0) { return Object.values(val); } return val; }) .flatMap((x) => x) .filter((x) => typeof x === "number") .reduce((a, b) => a + b, 0); }; const constructing = (construct) => { return Object.entries(construct).map((entry) => { if (typeof entry[1] === "object") { constructing(entry[1]); constructedTotals = { ...constructedTotals, [entry[0]]: calculateVals(Object.values(entry[1])), }; } else { console.log('here') } }); };
解决方案
你的现有代码只计算了当前对象内的数值之和,没有叠加内层对象已经计算好的结果。要实现需求,必须先递归处理最内层对象,再向外层计算,确保外层能直接复用内层的结果。
以下是正确的实现代码:
const calculateTotals = (obj) => { const result = {}; // 深度优先遍历,先处理最内层对象 const process = (currentObj) => { for (const [key, value] of Object.entries(currentObj)) { if (typeof value === 'object' && value !== null) { // 先递归处理子对象,确保子对象的结果已存入result process(value); // 计算当前对象自身的数值属性总和 const numSum = Object.values(value) .filter(v => typeof v === 'number') .reduce((acc, curr) => acc + curr, 0); // 找出当前对象中所有值为对象的属性键,累加它们在result中的结果 const childKeys = Object.keys(value).filter(k => typeof value[k] === 'object' && value[k] !== null); const childResultSum = childKeys.map(k => result[k] || 0).reduce((acc, curr) => acc + curr, 0); // 存入当前键的最终结果 result[key] = numSum + childResultSum; } } }; process(obj); return result; }; // 测试示例 const input = { "a":{ "a1":5, "b":{ "b1":10, "b2":15, "c":{ "c1":15 } } } }; console.log(calculateTotals(input)); // 输出 { c: 15, b: 40, a: 45 }
逻辑说明
- 遍历顺序:采用深度优先遍历,先处理最内层的
c对象,计算出它的结果15并存入result。 - 逐层计算:处理
b对象时,先算出自身数值和10+15=25,再加上result中c的值15,得到40存入result。 - 最外层计算:处理
a对象时,算出自身数值和5,加上result中b的值40,得到45存入result。
内容的提问来源于stack exchange,提问作者Red Baron
相关产品推荐
相关产品推荐

