我试图理解递归横向。
我偶然发现了这个link,他们在上面写了一个这样的例子
let company = { // the same object, compressed for brevity
sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }],
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)); // 6700
现在,我去模糊地阅读了关于reduce
和of
的内容,我无法将其与本示例联系起来
在此回调中,我们得到两个参数sum&elem。总和是 reduce函数的最后一个返回值。例如最初 当回调在第一个元素上运行时,总和将为0 它将elem加到和并返回该值。在第二 迭代总和值将是第一个elem + 0,在第三次迭代中 将会是0 +第一个elem +第二个elem。
现在,该示例是数组,而对象是对象,但是我仍然无法连接如何 current.salary
等于薪水吗?
然后我真的无法理解这一行
for (let subdep of Object.values(department)) {
sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results
}
就像我了解他正在递归地调用sumSalaries一样,但是..对我来说仍然没有意义吗?
有人可以请详细解释一下吗?
答案 0 :(得分:1)
let subdep of Object.values(department)
当department
不是数组时,它将遍历值。当sumSalaries
首先使用company
进行调用,因为company
不是数组,所以我们按了下面这行代码。 company
的值是sales
数组和development
对象-这些值都传递到sumSalaries
中。
让我们看一下逻辑如何与纯数字值一起工作的简化示例:
const test = {
sites: 3800,
internals: 1300
}
let sum = 0;
for (let aggSalaries of Object.values(test)) {
sum += aggSalaries;
}
console.log(sum)
5100
我建议可以将代码简化为:
const company = {
sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }],
development: {
sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
internals: [{name: 'Jack', salary: 1300}]
}
};
function sumSalaries(department) {
return Array.isArray(department)
? department.reduce((prev, {salary}) => prev + salary, 0)
: Object.values(department).reduce((memo, value) => memo + sumSalaries(value), 0);
}
console.log(sumSalaries(company));
答案 1 :(得分:1)
让我们逐步完成代码:
function sumSalaries(department) {
sumSalaries
接受一个参数。最初,它将是一个对象company
,但是在对象属性的连续迭代中,它将是一个数组或一个对象。
if (Array.isArray(department)) {
我们有一个需要满足的条件。如果参数是一个数组,请使用reduce
对薪水值求和。最初company
对象不满足此条件。
sales
数组以及department
对象中的两个数组都将满足此条件。
reduce
return department.reduce((prev, current) => prev + current.salary, 0);
reduce
接受一个初始值0,该初始值始终是每次迭代中回调函数中的第一个参数。在这种情况下,它被称为prev
,但是对于“累加器”或acc
,它可以很容易地称为sum
。第二个参数current
是数组中的当前元素。
重要说明:这些数组中的元素都是对象。
因此,我们从prev
中传递0到current
中第一个数组对象开始,然后将在对象的salary属性中找到的值相加为零。此值在下一次迭代时作为prev
参数传递。我们一直在增加该值,直到没有更多元素可以迭代为止,然后返回结果。
} else {
let sum = 0;
company
对象和development
对象都符合此条件。
for (let subdep of Object.values(department)) {
sum += sumSalaries(subdep);
}
return sum;
}
}
在第一次迭代中,我们遍历了company
。它的值是一个数组(sales
)和另一个对象(development
)。数组和对象被反馈到函数中。减少数组并将值添加到sum
中,对象命中再次满足此条件,并且每个数组(sites
,internals
)再次反馈到函数中,并且他们的结果会被减少并加到总和中。
就是这样!希望有帮助。