Oliver Eyton-Williams ee1e8abd87
feat(curriculum): restore seed + solution to Chinese (#40683)
* feat(tools): add seed/solution restore script

* chore(curriculum): remove empty sections' markers

* chore(curriculum): add seed + solution to Chinese

* chore: remove old formatter

* fix: update getChallenges

parse translated challenges separately, without reference to the source

* chore(curriculum): add dashedName to English

* chore(curriculum): add dashedName to Chinese

* refactor: remove unused challenge property 'name'

* fix: relax dashedName requirement

* fix: stray tag

Remove stray `pre` tag from challenge file.

Signed-off-by: nhcarrigan <nhcarrigan@gmail.com>

Co-authored-by: nhcarrigan <nhcarrigan@gmail.com>
2021-01-12 19:31:00 -07:00

2.9 KiB

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5cd9a70215d3c4e65518328f 使用递归创建一个倒计时 1 305925 use-recursion-to-create-a-countdown

--description--

在上一个挑战,学习了怎样用递归来代替循环。现在来学习一个更复杂的函数,函数返回一个从 1 到传递给函数的指定数字的连续数字数组。

正如上一个挑战提到的,会有一个 base case。base case 告诉递归函数什么时候不在需要调用其自身。这是简单 情况,返回得到的值。还有 recursive call,继续用不同的参数调用自身。如果函数无误,一直执行直到 base case 为止。

比如,如果想写一个递归函数,返回一个数字 1n 的连续数组。这个函数需要接收一个参数n 代表起始数字。然后会持续的调用自身,传入一个比 n 更小的值一直到传入的值是 1 为止。函数如下:

function countup(n) {
  if (n < 1) {
    return [];
  } else {
    const countArray = countup(n - 1);
    countArray.push(n);
    return countArray;
  }
}
console.log(countup(5)); // [ 1, 2, 3, 4, 5 ]

起初,这似乎是违反直觉的,因为 n 的值递减,但是最终数组中的值却递增。 之所以发生这种情况,是因为在递归调用返回之后,才调用 push。 在将 n pushed 进数组时,count(n - 1) 已经调用赋值成功并返回了 [1, 2, ..., n - 1]

--instructions--

已经定义了一个函数 countdown,函数有一个参数(n)。函数应该基于参数 n 递归调用返回 n1 的连续数字的数组。如果函数以小于 1 的参数调用,函数应该返回空数组。 比如,用 n = 5 调用函数应该返回数组 [5, 4, 3, 2, 1]。 函数必需使用递归函数调用自身,不能使用任何形式的循环。

--hints--

countdown(-1) 应该返回一个空数组。

assert.isEmpty(countdown(-1));

countdown(10) 应该返回 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

assert.deepStrictEqual(countdown(10), [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);

countdown(5) 应该返回 [5, 4, 3, 2, 1]

assert.deepStrictEqual(countdown(5), [5, 4, 3, 2, 1]);

代码不能包含任意形式的循环(forwhile 或者高阶函数如:forEachmapfilter 以及 reduce)。

assert(!removeJSComments(code).match(/for|while|forEach|map|filter|reduce/g));

应该用递归解决这个问题。

assert(removeJSComments(countdown.toString()).match(/countdown\s*\(.+\)\;/));

--seed--

--seed-contents--

// Only change code below this line
function countdown(n){
  return;
}
// Only change code above this line

--solutions--

function countdown(n){
   return n < 1 ? [] : [n].concat(countdown(n - 1));
}