let 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}]
}
};
// The function to do the job
function sumSalaries(department) {
if (Array.isArray(department)) { // case (1)
return department.reduce((prev, current) => prev + current.salary, 0); // sum the array
} else { // case (2)
let sum = 0;
for (let subdep of Object.values(department)) {
sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results
}
return sum;
}
}
alert(sumSalaries(company)); // 7700
最佳答案
/* 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) */ }
<小时/>
但是该代码有一些奇怪的地方。首先,它使用 reduce
对一种情况下的值求和,并使用 sum = 0 ... for (...) { sum += ... } ... return sum
为其他;这感觉很奇怪。其次,它对要作为参数提供给递归调用的内部变量使用完全不同的变量名称。但数据结构并没有表明这一点;公司的结构与任何部门或子部门相同。 “department”
和 “subdep”
之间的区别使得更难了解问题的递归本质。通常,当我需要数据结构的两个不同名称时,我会尝试使这些名称看起来对齐。例如,我可能会使用缩写 dept
而不是 subdep
。
所以,我会以不同的方式写这个。这是一个不同的版本,使用辅助函数对数字数组求和。虽然看起来很不同,但底层逻辑完全相同:
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))
关于javascript - 递归,递归应用示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60587625/