/* 1 */ function sumSalaries(department) {
/* 2 */ if (Array.isArray(department)) { // case (1)
/* 3 */ return department.reduce((prev, current) => prev + current.salary, 0); // sum the array
/* 4 */ } else { // case (2)
/* 5 */ let sum = 0;
/* 6 */ for (let subdep of Object.values(department)) {
/* 7 */ sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results
/* 8 */ }
/* 9 */ return sum;
/* 10 */ }
/* 11 */ }
/* (1) */ sumSalaries (company) {
/* (2) */ Array .isArray (company) //=> false, so hit branch 2
/* (5) */ sum = 0
/* (6) */ Object .values (company) //=> [<sales>, <development>]
/* (6) */ [<sales>, <development>] .for Each ...
/* (7) */ sumSalaries (<sales>) {
/* (2) */ Array .isArray (<sales>) //=> true, so hit branch 1 // John Alice
/* (3) */ <sales>.reduce((prev, current) => prev + current.salary, 0) //=> 0 + 1000 + 1600 = 2600
/* (3) */ return 2600
/* (10) */ }
/* (7) */ sum = 0 + 2600 = 2600
/* (7) */ sumSalaries (<development>) {
/* (2) */ Array.isArray (<development) //=> false, so hit branch 2
/* (5) */ sum = 0 // (different instance of `sum` from above)
/* (6) */ Object.values (<development>) //=> [<sites>, <internal>]
/* (6) */ [<sites>, <internal>] .for Each ...
/* (7) */ sumSalaries (<sites>) {
/* (2) */ Array.isArray (<sites>) //=> true, so hit branch 1 // Peter Alex
/* (3) */ <sites>.reduce((prev, current) => prev + current.salary, 0) //=> 0 + 2000 + 1800 = 3800
/* (3) */ return 3800
/* (10) */ }
/* (7) */ sum = 0 + 3800
/* (7) */ sumSalaries (<internals>) {
/* (2) */ Array.isArray (<internals>) //=> true, so hit branch 1 Jack
/* (3) */ <internals>.reduce((prev, current) => prev + current.salary, 0) //=> 0 + 1300 = 1300
/* (10) */ return 1300
/* (10) */ }
/* (7) */ sum = 3800 + 1300 = 5100
/* (9) */ return 5100
/* (10) */ }
/* (7) */ sum = 2600 + 5100 = 7700 // (back to the original `sum`)
/* (9) */ return 7700
/* (11) */ }
But there is something odd about that code. First, it uses reduce to total the values in one case and sum = 0 ... for (...) { sum += ... } ... return sum for the other; that feels odd. Second, it uses a substantially different variable name for the internal variable you're going to supply as a parameter to the recursive call. But the data structure does not suggest that; the company is structured the same as any department or sub-department. This distinction between "department" and "subdep" makes it more difficult to get a feeling for the recursive nature of the problem. Usually, when I need two different names for the data structure, I try to make the names seem aligned. I might, for instance, use the abbreviation dept instead of subdep.
So, I would write this differently. Here's a different version, using a helper function which sums an array of numbers. While it looks quite different, the underlying logic is entirely the same:
const sum = (ns) => ns .reduce ((t, n) => t + n, 0)
const sumSalaries = (department) =>
Array .isArray (department)
? sum (department .map (empl => empl .salary))
: sum (Object .values (department) .map (sumSalaries))
const company = {sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }], development: {sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }], internals: [{name: 'Jack', salary: 1300}]}}
console .log (sumSalaries (company))