有一个"值"或/和"孩子"作为属性。问题是添加所有值并返回总和。这很有效。我用过递归。我使用全局变量来存储总和。
请参阅 - https://jsfiddle.net/ws6ty78b/1/
function sumup(node) {
sum+=node.value;
if (node.children && node.children.length > 0) {
for (var i =0; i < node.children.length; i++) {
sumup(node.children[i]);
}
}
return sum
}
问题 - 再次调用相同的函数时,我得不到相同的结果。总和翻倍。我知道为什么会发生这种情况,因为我使用的是全局变量。
问题 - 对于上述问题,有没有办法可以为任意数量的调用获得相同的结果。
请注意限制 -
1)不要更改功能签名和声明。
2)使用&#39;总和&#39;总结里面的变量&#39;功能
3)不要使用任何额外的变量。
4)仅在总和函数中进行更改。
答案 0 :(得分:2)
您可以简单地将每个子项的值与当前节点的值相加:
function sumup(node) {
sum=node.value;
if (node.children && node.children.length > 0) {
for (var i =0; i < node.children.length; i++) {
sum+=sumup(node.children[i]);
}
}
return sum
}
答案 1 :(得分:0)
为了实现目标,函数sumup()
将被调用N次。我们不知道这个N是多少,因为它取决于子节点的递归次数。此外,由于这些限制,我们无法编辑函数签名,也无法在其他地方编写代码来执行任何操作,甚至不能手动将sum设置为0。
因此我们需要一种方法来区分一堆调用和NEXT串,并重置它。
我的想法是设置一个阈值,使用closure。从第一次调用开始,在示例中,您有5秒的时间来保持呼叫,之后它将重新开始。除非提供另一种区分调用的方法,否则这就是我们所能做的全部。
编辑:我在这里尝试的是将所有递归作为基本案例并且不改变对象。由于OP接受了该解决方案,我正在添加节点重置器属性。如果任何节点未定义重置器或为null或零或未定义,则将重置总和。我们必须假设它没有在已启动的对象中定义。正如我所说,这是一个弱假设。通过在递归时定义它,当前总和被转移。 我还将保留最初的时间阈值理念,以便最终获得利益。
var obj = {
"value": 4,
"children": [
{
"value": 2,
"children": [
{
"value": 1
}
]
},
{
"value": 9
}
]
}
const sumup = (function(){
var lastTime = 0;
var newTime = 0;
var sum = 0;
const timeThreshold = 5000; // 5 seconds
return function(node) {
newTime = new Date().getTime();
if(!node["resetter"] || (newTime-lastTime >= timeThreshold)){
sum=0;
lastTime = newTime;
}
sum+=node.value;
if (node.children && node.children.length > 0) {
for (var i =0; i < node.children.length; i++) {
sumup(Object.assign({"resetter":true},node.children[i]));
}
}
return sum;
}
})();
console.log(sumup(obj)); //16
console.log(sumup(obj)); //32! should print 16 everytime
答案 2 :(得分:0)
您可以在递归时对call
进行总结,并针对自定义this
进行分配/测试:
var obj = {
"value": 4,
"children": [{
"value": 2,
"children": [{
"value": 1
}]
},
{
"value": 9
}
]
};
var sum = 0;
function sumup(node) {
//Only make change within this function body
if (!this || !this.recurse) sum = 0;
sum += node.value;
if (node.children && node.children.length > 0) {
for (var i = 0; i < node.children.length; i++) {
sumup.call({ recurse: true }, node.children[i]);
}
}
return sum
}
console.log(sumup(obj));
console.log(sumup(obj));
&#13;
或者,您可以完全取消全局变量,并在子项上使用递归reduce
:
var obj = {
"value": 4,
"children": [{
"value": 2,
"children": [{
"value": 1
}]
},
{
"value": 9
}
]
};
const sumup = (node) => (
node.value + (node.children
? node.children.reduce((a, child) => a + sumup(child), 0)
: 0
)
);
console.log(sumup(obj));
console.log(sumup(obj));
&#13;