I am trying to get the sum of tasks completed using recursion. An object represents a team member and they can manage other members.
var team = {
name: 'Rufus',
completedTasks: 4,
manages: [
{
name: 'Clara',
completedTasks: 6,
manages: [
{
name: 'Dana',
completedTasks: 12,
manages: []
}
]
},
{
name: 'Charles',
completedTasks: 19,
manages: []
}
]
};
This is what I have implemented, but I am not getting 41. 4 6 12 19 = 41. The function is returning 45.
var totalTasks = function (team) {
var sum = 0;
var innerFunction = function(obj) {
if (obj.manages.length === 0) {
sum = obj.completedTasks;
return;
}
obj.manages.forEach(function(item) {
sum = obj.completedTasks;
innerFunction(item);
});
};
innerFunction(team);
return sum;
};
totalTasks(team);
CodePudding user response:
This happens because in your forEach
loop you add obj.completedTasks
which has nothing to do with the looped item, and so you are adding the same number in every iteration.
Keep the adding limited to only add obj.completedTasks
once (as the first thing to do), unconditionally. So:
var team = {name: 'Rufus',completedTasks: 4,manages: [{name: 'Clara',completedTasks: 6,manages: [{name: 'Dana',completedTasks: 12,manages: []}]},{name: 'Charles',completedTasks: 19,manages: []}]};
var totalTasks = function (team) {
var sum = 0;
var innerFunction = function(obj) {
sum = obj.completedTasks;
if (obj.manages.length === 0) return;
obj.manages.forEach(innerFunction);
};
innerFunction(team);
return sum;
};
console.log(totalTasks(team));
It is nicer if you don't manage sum
as a non-local variable, but just accumulate it recursively:
var team = {name: 'Rufus',completedTasks: 4,manages: [{name: 'Clara',completedTasks: 6,manages: [{name: 'Dana',completedTasks: 12,manages: []}]},{name: 'Charles',completedTasks: 19,manages: []}]};
var totalTasks = team =>
team.completedTasks
team.manages.reduce((sum, child) => sum totalTasks(child), 0);
console.log(totalTasks(team));
CodePudding user response:
The problem with your code is that you wrote:
sum = obj.completedTasks;
instead of
sum = item.completedTasks;
inside the foreach which means that the outer person's completed tasks is getting added instead of the inner person's.
Regardless, it seemed your function was overcomplicated and could be shortened.
function allTasks (person)
{
return person.completedTasks person.manages.map(allTasks).reduce((a, b) => a b, 0);
}
var team = {
name: 'Rufus',
completedTasks: 4,
manages: [
{
name: 'Clara',
completedTasks: 6,
manages: [
{
name: 'Dana',
completedTasks: 12,
manages: []
}
]
},
{
name: 'Charles',
completedTasks: 19,
manages: []
}
]
};
function allTasks (person)
{
return person.completedTasks person.manages.map(allTasks).reduce((a, b) => a b, 0);
}
console.log(allTasks(team));
CodePudding user response:
The following code will solve the problem.
function totalTasks(item){
if (item.manages.length){
return item.completedTasks item.manages.reduce((sum,item) => sum totalTask(item), 0 )
}
return item.completedTasks
}
totalTasks(team);