父值是嵌套javascript对象中所有子值的总和

父值是嵌套javascript对象中所有子值的总和,javascript,recursion,lodash,Javascript,Recursion,Lodash,我有一个嵌套很深的javascript对象,有无限多的子对象。每个孩子都有一个值和一个总值。totalValue应该是其所有子级和子级的所有值的总和。我怎样才能做到这一点 目前,我只能使用递归函数循环整个对象: // Recursive function _.each(names, function(parent) { if(parent.children.length > 0) { recursiveFunction(parent.children);

我有一个嵌套很深的javascript对象,有无限多的子对象。每个孩子都有一个值和一个总值。totalValue应该是其所有子级和子级的所有值的总和。我怎样才能做到这一点

目前,我只能使用递归函数循环整个对象:

// Recursive function
_.each(names, function(parent) { 
    if(parent.children.length > 0) { 
        recursiveFunction(parent.children);
    }
});

function recursiveFunction(children){ 
    _.each(children, function(child) { 
        if(child.children.length > 0) { 
            recursiveFunction(child.children)
        }
    });
}; 

// Deeply nested javascript object
var names = {
    name: 'name-1',
    value: 10,
    valueTotal: 0, // should be 60 (name-1.1 + name-1.2 + name-1.2.1 + name-1.2.2 + name-1.2.2.1 + name-1.2.2.2)
    children: [{
            name: 'name-1.1',
            value: 10,
            valueTotal: 0,
            children: []
        }, {
            name: 'name-1.2',
            value: 10,
            valueTotal: 0, // should be 40 (name-1.2.1 + name-1.2.2 + name-1.2.2.1 + name-1.2.2.2)
            children: [{
                name: 'name-1.2.1',
                value: 10,
                valueTotal: 0,
                children: []
            }, {
                name: 'name-1.2.2',
                value: 10,
                valueTotal: 0, // should be 20 (name-1.2.2.1 + name-1.2.2.2)
                children: [{
                    name: 'name-1.2.2.1',
                    value: 10,
                    valueTotal: 0,
                    children: []
                }, {
                    name: 'name-1.2.2.2',
                    value: 10,
                    valueTotal: 0,
                    children: []
                }]
            }]
        }]
    }
}

所以事实上你想做这样的事情: 每个元素都会向他的孩子索要其价值观,这些孩子也会这样做,并返回他们的总价值加上他们自己的价值观

function sumUp(object){
  object.totalValue = 0;
  for(child of object.children){
    object.totalValue += sumUp(child);
   }
   return object.totalValue + object.value;
}
这样开始:

const totalofall = sumUp(names);
console.log(names); //your expected result.
工作示例:

您可以使用简单的Javascript,使用迭代和递归方法,并对本地总计进行一些健全性检查

函数计算值(o){
o、 valueTotal=(o.children | |[])。reduce(函数(r,a){
计算价值(a);
返回r+(a.value | | 0)+(a.valueTotal | 0);
}, 0);
}
变量名称={name:'name-1',值:10,valueTotal:0,子项:[{name:'name-1.1',值:10,valueTotal:0,子项:[{name:'name-1.2',值:10,valueTotal:0,子项:[{name:'name-1.2.2',值:10,valueTotal:0,子项:[},{name:'name:'name-1.2.2',value:0,子项:[{name:'name-1.2.2.1',值:10,valueTotal:0,子项:[]},{name:'name-1.2.2.2',值:10,valueTotal:0,子项:[]};
计算值(名称);
console.log(名称);

.as控制台包装{最大高度:100%!重要;顶部:0;}
不太喜欢重新发明轮子,建议使用一个库以提高可读性和可维护性。我们现在使用它来处理大部分数据。一旦你想清楚如何使用它,它就非常通用了。无论如何,这里有一个可能解决你的问题的方法

//const objectScan=require('object-scan');
常量和=(数据)=>{
objectScan(['**.children']{
filterFn:({parent,value:children})=>{
parent.valueTotal=子项
.map({valueTotal,value})=>valueTotal+value)
.减少((a,b)=>a+b,0);
}
})(数据);
};
const names={name:'name-1',value:10,valueTotal:0,子项:[{name:'name-1.1',value:10,valueTotal:0,子项:[{name:'name-1.2.2',value:10,valueTotal:0,子项:[},{name:'name-1.2.2',value:0,子项:[{name:'name-1.2.2.1',值:10,valueTotal:0,子项:[]},{name:'name-1.2.2.2',值:10,valueTotal:0,子项:[]};
(姓名);
console.log(名称);
//=>{name:'name-1',value:10,valueTotal:60,子项:[{name:'name-1.1',value:10,valueTotal:0,子项:[},{name:'name-1.2',value:10,valueTotal:40,子项:[{name:'name-1.2.2',value:10,valueTotal:20,子项:[{name:'name-1.2.2.1',值:10,valueTotal:0,子项:[]},{name:'name-1.2.2.2',值:10,valueTotal:0,子项:[]}
。作为控制台包装{最大高度:100%!重要;顶部:0}

您的总和看起来是错误的,name-2是name-1的子节点,应该包括在内。您是对的!我会更改它。我有点困惑,我的目标不是获取对象中所有值的总值。我试图用每个节点的子节点/子节点值的总和来填充每个节点的总值。结果应该是相同的列表但是在填充了所有totalValue之后(仅当该节点包含子节点时)。@Sam它通过object.totalValue+=summup(子节点)执行操作;查看已记录的示例树。您会发现totalValue包含您正在搜索的内容。我确实看错了,我会尽快测试它并让您知道它是否有效!请编辑您的响应,我将删除一个否决票(我的错误,看起来这些值实际上是正确的)如果您想重温老问题,展示
对象扫描
如何帮助您回答这些问题,请放心,如果这只是您的新锤子,因此一切看起来都像钉子,那也没关系。但是如果您与
对象扫描
有重要联系,请附上免责声明。(例如,在讨论Ramda时,我添加了类似“(免责声明:我是Ramda的主要作者之一)”的内容。)因为感觉好像你想在这里卖东西。请试着写一篇关于JS答案的文章。你可以用类似
的东西来代替你的
导入
语句。@ScottSauyet谢谢你的反馈。我的意图显然不是卖任何东西,而是用这些老问题作为我的学习练习如果。但你是绝对正确的,我会仔细检查我的答案,稍后用免责声明更新。如果你连接到图书馆(可能是主要的贡献者或资助者),免责声明很重要。否则,这是没有必要的。我只是看到你最近对一些旧问题的回答的相同介绍,我想知道它。