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

时间:2017-01-19 15:36:46

标签: javascript recursion lodash

我有一个深度嵌套的javascript对象,其中包含无限的儿童。每个孩子都有一个值和一个totalValue。 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: []
                }]
            }]
        }]
    }
}

3 个答案:

答案 0 :(得分:3)

所以事实上你想做这样的事情: 每个元素都会询问孩子的价值观,他们也会这样做,并将他们的总价值加上他们自己的价值。

function sumUp(object){
object.totalValue=0;
for(child of object.children){
 object.totalValue+=sumUp(child);
}
return object.totalValue+object.value;
}

像这样开始:

totalofall=sumUp(names);
console.log(names);//your expected result.

工作示例: http://jsbin.com/laxiveyoki/edit?console

答案 1 :(得分:1)

你可以使用普通的Javascript来进行迭代和递归的方法,并对局部总数进行一些健全性检查。

Task.WhenAll(t1, t2, t3).Wait();
function calculateValues(o) {
    o.valueTotal = (o.children || []).reduce(function (r, a) {
        calculateValues(a);				
        return r + (a.value || 0) + (a.valueTotal || 0);
    }, 0);
}

var names = { name: 'name-1', value: 10, valueTotal: 0, children: [{ name: 'name-1.1', value: 10, valueTotal: 0, children: [] }, { name: 'name-1.2', value: 10, valueTotal: 0, children: [{ name: 'name-1.2.1', value: 10, valueTotal: 0, children: [] }, { name: 'name-1.2.2', value: 10, valueTotal: 0, children: [{ name: 'name-1.2.2.1', value: 10, valueTotal: 0, children: [] }, { name: 'name-1.2.2.2', value: 10, valueTotal: 0, children: [] }] }] }] };

calculateValues(names);
console.log(names);

答案 2 :(得分:0)

不太喜欢重新设计轮子,建议使用库来提高可读性和可维护性。我们现在将object-scan用于我们的大多数数据处理,因为一旦您掌握了如何使用它,它就会变得强大。无论如何,这是您问题的可能解决方案

const objectScan = require('object-scan');

const injectSums = (data) => {
  objectScan(['**.children'], {
    filterFn: ({ parent, value: children }) => {
      parent.valueTotal = children
        .map(({ valueTotal, value }) => valueTotal + value)
        .reduce((a, b) => a + b, 0);
    }
  })(data);
};

const names = {"name":"name-1","value":10,"valueTotal":0,"children":[{"name":"name-1.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2","value":10,"valueTotal":0,"children":[{"name":"name-1.2.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2.2","value":10,"valueTotal":0,"children":[{"name":"name-1.2.2.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2.2.2","value":10,"valueTotal":0,"children":[]}]}]}]};

injectSums(names);

console.log(JSON.stringify(names));
// => {"name":"name-1","value":10,"valueTotal":60,"children":[{"name":"name-1.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2","value":10,"valueTotal":40,"children":[{"name":"name-1.2.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2.2","value":10,"valueTotal":20,"children":[{"name":"name-1.2.2.1","value":10,"valueTotal":0,"children":[]},{"name":"name-1.2.2.2","value":10,"valueTotal":0,"children":[]}]}]}]}