【问题标题】:How to find sum of a specific property in nested JS object如何在嵌套的 JS 对象中查找特定属性的总和
【发布时间】:2021-09-28 20:24:49
【问题描述】:
我想计算这个对象中所有“val”的总和。最终输出应该是 113。我尝试搜索但在 stackoverflow 上找不到类似的问题。
const object = {
val: 10,
child: [
{
val: 20,
child: [
{
val: 25,
child: []
},
{
val: 28,
child: []
}
]
},
{
val: 30,
child: []
}
]
};
我尝试的是这个。我知道这不是最好的方法,并希望看到更好的方法。
const object = {
val: 10,
child: [
{
val: 20,
child: [
{
val: 25,
child: []
},
{
val: 28,
child: []
}
]
},
{
val: 30,
child: []
}
]
};
function sum() {
let k = object.val;
if(object.child.length>0){
object.child.map(item => {
k += item.val;
if(item.child.length>0){
item.child.map(item => k += item.val)
}
})
}
return k
}
const result = sum(object);
console.log(result);
你可以在这里找到问题 - https://codesandbox.io/s/young-night-ulnfl?file=/src/index.js
我也在想像 flat() 这样的东西可能会有所帮助,但这仅适用于数组。
【问题讨论】:
标签:
javascript
html
jquery
arrays
object
【解决方案1】:
递归Array#reduce()
const object = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] };
const sumObjectVals = (arr) => arr
.reduce((a, obj) => (
a += (obj.child.length
? obj.val + sumObjectVals(obj.child)
: obj.val), a), 0);
console.log(sumObjectVals([object]))
【解决方案2】:
你可以创建一个递归节点访问函数。
const tree = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] }
const visitNodes = (obj, visitor, key) => {
if (typeof obj === 'object') {
for (let key in obj) {
visitNodes(obj[key], visitor, key);
}
} else {
visitor(obj, key);
}
};
let total = 0;
visitNodes(tree, (val, key) => {
if (key === 'val') {
total += val;
}
});
console.log(`Total: ${total}`);
或者,您可以拥有一个可以为您添加所有值的累加器。
编辑:更改了函数签名以采用自定义“子”属性。
const tree = { val: 10, child: [{ val: 20, child: [{ val: 25, child: [] }, { val: 28, child: [] }] }, { val: 30, child: [] }] }
const accumulateValues = (obj, visitor, childProp = null, acc = 0) => {
if (typeof obj === 'object') {
acc += visitor(obj);
if (Array.isArray(obj[childProp])) {
acc += obj[childProp].reduce((acc, child) =>
accumulateValues(child, visitor, childProp, acc), 0);
}
}
return acc;
};
const total = accumulateValues(tree, ({ val }) => val, 'child');
console.log(`Total: ${total}`);
【解决方案3】:
const object = {
val: 10,
child: [
{
val: 20,
child: [
{
val: 25,
child: []
},
{
val: 28,
child: []
}
]
},
{
val: 30,
child: []
}
]
};
function sum(obj, summ) {
summ += obj.val;
if(obj.child.length > 0) {
obj.child.forEach(x => summ = sum(x, summ))
}
return summ;
}
const result = sum(object, 0);
console.log(result);
【解决方案4】:
// 可以使用多个reduce数组方法得到结果。
const object = {
val: 10,
child: [
{
val: 20,
child: [
{
val: 25,
child: []
},
{
val: 28,
child: []
}
]
},
{
val: 30,
child: []
}
]
};
const results = object.child.reduce((totals, current)=> {
const innerResult = current.child.reduce((total, cur) => {
return total + cur.val
}, 0);
return totals + current.val + innerResult;
}, object.val);
console.log(results);