javascript - Javascript unshift(),递归和制作数组
问题描述
function countdown(n) {
if (n < 1) {
return [];
} else {
const arr = countdown(n - 1);
arr.unshift(n);
return arr;
}
}
我在 freeCodeCamp 中找到了上面的代码。我在 VS 代码上运行它。它有效,但我不明白如何。这是我的问题:您如何unshift()
处理尚未声明为数组的变量,例如[]
?它只是这么说const arr = countdown(n-1)
。它并没有说那const arr
是一个数组,例如“ []
”。如果我尝试将unshift()
整数转换为已声明为“ arr
”而没有任何“ []
”的变量,它将作为错误运行。但是,在我在 freeCodeCamp 上找到的这段代码中,它可以工作。为什么?
解决方案
替代
如果我说x = 5
然后问“什么是x + 3
?” . 无需太多帮助就可以回答,8。当你被问到你是如何得出答案的时,你解释说你用它的值代替 x
了五,然后加了三。
如果给定一个函数f(x) = 3 * x + 2
or max(a,b) = a > b ? a : b
,我可以问你其他问题,比如什么是f(4)
or max(9,7)
?你会以同样的方式得到答案:
- 是什么
f(4)
?- 是什么
f
?→f
是x -> 3 * x + 2
- 是什么
x
?→x
是4
- 是什么
3 * 4 + 2
?- 是什么
3 * 4
?→ 答案是12
- 是什么
12 + 2
?→ 答案是14
- 答案是
14
- 是什么
- 答案是
14
- 是什么
- 答案是
14
- 是什么
max(9,7)
?- 是什么
max
?→max
是(a,b) => a > b ? a : b
a
和是什么b
?→a
是9
和b
是7
- 是什么
9 > 7 ? 9 : 7
?- 是什么
9 > 7
?→ 答案是true
- 是什么
true ? 9 : 7
?→ 答案是9
- 答案是
9
- 是什么
- 答案是
9
- 是什么
- 答案是
9
因此,使用递归函数,我们可以使用替换来回答这些问题
- 是什么
countdown(5)
?- 是什么
countdown
?countdown
是function countdown(n) { if (n < 1) { return []; } else { const arr = countdown(n - 1); arr.unshift(n); return arr; } }
- 是什么
n
?→n
是5
- 什么是 ...?
if (5 < 1) { return []; } else { const arr = countdown(5 - 1); arr.unshift(5); return arr; }
- 是什么
5 < 1
。→ 答案是false
- 什么是 ...?
if (false) { return []; } else { const arr = countdown(5 - 1); arr.unshift(5); return arr; }
- 答案是
const arr = countdown(5 - 1); arr.unshift(5); return arr;
- 是什么
arr
?- 答案是
countdown(5 - 1)
- 是什么
5 - 1
?→ 答案是4
- 是什么
countdown(4)
?
- 答案是
- 答案是
- 是什么
- 是什么
那是arr
什么?
使用替换来计算countdown(5)
导致我们计算countdown(4)
,我们可以再次使用替换。countdown(4)
看起来和以前几乎一模一样,当你继续往下看时countdown(3)
,countdown(2)
我们会注意到这种n - 1
模式正在发挥作用。直到最后n = 0
,条件n < 1
是现在true
......
- 是什么
countdown(0)
?- 答案是
[]
- 答案是
我们可以一直使用替换 -
- 是什么
countdown(3)
?- 是什么
arr
? arr
是countdown(3 - 1)
- 是什么
countdown(2)
?- 是什么
arr
? arr
是countdown(2 - 1)
- 是什么
countdown(1)
?- 是什么
arr
? arr
是countdown(1 - 1)
- 是什么
countdown(0)
?- 答案是
[]
- 答案是
arr
是[]
- 是什么
arr.unshift(1)
?→ * 答案是[1]
- 答案是
[1]
- 是什么
arr
是[1]
- 是什么
arr.unshift(2)
?→ 答案是[2,1]
- 答案是
[2,1]
- 是什么
arr
是[2,1]
- 是什么
arr.unshift(3)
?→ 答案是[3,2,1]
- 答案是
[3,2,1]
- 是什么
- 答案是
[3,2,1]
一个警告
递归是一种功能性遗产,因此将其与功能性原则一起使用会产生最佳结果。这意味着避免诸如突变、变量重新分配和其他副作用之类的事情。上面我们可以使用替换,因为countdown
具有引用透明性。这是一种奇特的说法,如果给出相同的输入,该函数总是返回相同的结果。在函数学科中,您总是以这种方式设计函数,因此您的程序可以组装和组合,就像不断发展的方程组中的公式一样。
没有arr
JavaScript 对函数式风格有很强的支持,所以我们的程序可以用丰富的表达式来编写。程序语义不受中间赋值arr
和语法样板(如if
, else
, return
, 和{...}
lie about)的干扰。
const countdown = n =>
n < 1
? []
: [ n, ...countdown(n - 1) ]
console.log(countdown(5))
[5,4,3,2,1]
推荐阅读
- c# - 如何“将 .XML 数据显示到 listView1 的每一列”?C# Windows 窗体
- git - Git:如何压缩“master”分支上的所有提交?
- google-sheets - Google 电子表格数据库导入错误:无法保存 ID 为 [--ID--] 的文档:文档太大
- java - 标准对话框按钮样式到 JFoenix
- excel - 如何使用分配给按钮的代码将隐藏在表格底部一行中的公式复制到位于同一列中的活动单元格?
- sql - 避免在 postgres plpgsql 函数中几乎重复查询
- excel - 在单元格文本中查找字符串(VB)
- python - 如何根据A列中的值合并B列中的值
- mysql - 如何将可重复的分区作为一个又一个分区的新分区?
- javascript - 标记的形状 - 可点击区域