递归,递归的应用示例 [英] Recursion, example of application of the recursion

查看:47
本文介绍了递归,递归的应用示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 和案例 2 的总和?

This code is about using recursion in calculation of total salary in company's departments. Please, explain to me this. In the example of tutorial, recursive traversals, after running the first case (we calculate the salary in sales department) function return this salary. So why it proceed further and calculate another case (development department) if we have return statement in first calculation? Shouldn't it break the flow? And how it sum the case 1 and total sum of case 2?

推荐答案

/*  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.


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))

这篇关于递归,递归的应用示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆