[英]Javascript unshift(), recursion and making an array
function countdown(n) {
if (n < 1) {
return [];
} else {
const arr = countdown(n - 1);
arr.unshift(n);
return arr;
}
}
I found the above code in freeCodeCamp.我在 freeCodeCamp 中找到了上面的代码。 I ran it on VS code.
我在 VS 代码上运行它。 It works, but I don't understand how.
它有效,但我不明白如何。 Here is my question: How can you
unshift()
onto a variable that has not yet been declared as an array such as []
?这是我的问题:如何将
unshift()
移到尚未声明为数组(例如[]
unshift()
的变量上? It just says that const arr = countdown(n-1)
.它只是说
const arr = countdown(n-1)
。 It does not say that const arr
is an array such as " []
".它并没有说
const arr
是一个数组,例如“ []
”。 If I try to unshift()
integers onto a variable that has been declared as just " arr
" without any " []
", it runs as an error.如果我尝试将
unshift()
整数移到已声明为“ arr
”而没有任何“ []
”的变量上,它将作为错误运行。 However, in this code that I found on freeCodeCamp, it works.但是,在我在 freeCodeCamp 上找到的这段代码中,它可以工作。 Why?
为什么?
substitution代换
If I say x = 5
and then ask "What is x + 3
?"如果我说
x = 5
然后问“ x + 3
什么?” . . Without much help one can answer, 8 .
无需太多帮助即可回答, 8 。 When you are asked how you arrived at your answer, you explain that you substituted
x
with its value, five, and then added plus three.当您被问及如何得出答案时,您解释说您用
x
的值 5替换了x
,然后加上了 3。
If given a function f(x) = 3 * x + 2
or max(a,b) = a > b ? a : b
如果给定函数
f(x) = 3 * x + 2
或max(a,b) = a > b ? a : b
max(a,b) = a > b ? a : b
, I can ask you other questions like what is f(4)
or max(9,7)
? max(a,b) = a > b ? a : b
,我可以问你其他问题,比如什么是f(4)
或max(9,7)
? And you'll arrive at the answer the same way:你会以同样的方式得出答案:
f(4)
?f(4)
?
f
?f
? → f
is x -> 3 * x + 2
f
是x -> 3 * x + 2
x
? x
是什么? → x
is 4
x
是4
3 * 4 + 2
?3 * 4 + 2
?
3 * 4
?3 * 4
? → The answer is 12
12
12 + 2
?12 + 2
? → The answer is 14
14
14
14
14
14
14
14
max(9,7)
?max(9,7)
?
max
?max
? → max
is (a,b) => a > b ? a : b
max
是(a,b) => a > b ? a : b
(a,b) => a > b ? a : b
a
and b
?a
和b
? → a
is 9
and b
is 7
a
是9
而b
是7
9 > 7 ? 9 : 7
9 > 7 ? 9 : 7
9 > 7 ? 9 : 7
? 9 > 7 ? 9 : 7
?
9 > 7
?9 > 7
? → The answer is true
true
true ? 9 : 7
true ? 9 : 7
true ? 9 : 7
? true ? 9 : 7
? → The answer is 9
9
9
9
9
9
9
9
And so with a recursive function, we can use substitution to answer these questions所以使用递归函数,我们可以使用替换来回答这些问题
countdown(5)
?countdown(5)
?
countdown
?countdown
?
countdown
is countdown
是function countdown(n) { if (n < 1) { return []; } else { const arr = countdown(n - 1); arr.unshift(n); return arr; } }
n
?n
? → n
is 5
n
是5
if (5 < 1) { return []; } else { const arr = countdown(5 - 1); arr.unshift(5); return arr; }
5 < 1
.5 < 1
。 → The answer is false
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
?arr
?
countdown(5 - 1)
countdown(5 - 1)
5 - 1
?5 - 1
? → The answer is 4
4
countdown(4)
?countdown(4)
? so what is arr
?那么什么是
arr
?
Using substitution to compute countdown(5)
leads us to compute countdown(4)
, where again we can use substitution.使用替换来计算
countdown(5)
导致我们计算countdown(4)
,我们可以再次使用替换。 countdown(4)
will look almost exactly the same as before, and as you continue on with countdown(3)
and countdown(2)
we notice the n - 1
pattern play out. countdown(4)
看起来几乎和以前一样,当你继续countdown(3)
和countdown(2)
我们注意到n - 1
模式出现了。 Until finally n = 0
and the conditional n < 1
is now true
...直到最后
n = 0
并且条件n < 1
现在为true
...
countdown(0)
?countdown(0)
?
[]
[]
We can use substitution all the way -我们可以一直使用替换——
countdown(3)
?countdown(3)
?
arr
?arr
?arr
is countdown(3 - 1)
arr
是countdown(3 - 1)
countdown(2)
?countdown(2)
?
arr
?arr
?arr
is countdown(2 - 1)
arr
是countdown(2 - 1)
countdown(1)
?countdown(1)
?
arr
?arr
?arr
is countdown(1 - 1)
arr
是countdown(1 - 1)
countdown(0)
?countdown(0)
?
[]
[]
arr
is []
arr
是[]
arr.unshift(1)
?arr.unshift(1)
? → * The answer is [1]
[1]
[1]
[1]
arr
is [1]
arr
是[1]
arr.unshift(2)
?arr.unshift(2)
? → The answer is [2,1]
[2,1]
[2,1]
[2,1]
arr
is [2,1]
arr
是[2,1]
arr.unshift(3)
?arr.unshift(3)
? → The answer is [3,2,1]
[3,2,1]
[3,2,1]
[3,2,1]
[3,2,1]
[3,2,1]
one caveat一个警告
Recursion is a functional heritage and so using it with functional discipline yields the best results.递归是一种函数式遗产,因此将它与函数式学科结合使用会产生最好的结果。 This means avoiding things like mutation, variable reassignment, and other side effects.
这意味着避免诸如突变、变量重新分配和其他副作用之类的事情。 Above we can use substitution because
countdown
has referential transparency .上面我们可以使用替换,因为
countdown
具有参考透明度。 That's a fancy way to say that the function always returns the same result if the same inputs were given.这是一种奇特的说法,如果给出相同的输入,函数总是返回相同的结果。 In functional discipline you always design functions in this way, so your programs can be assembled and combined, like formulas in an evolving system of equations.
在函数式学科中,您总是以这种方式设计函数,因此您的程序可以组装和组合,就像不断发展的方程系统中的公式一样。
there is no arr
没有
arr
JavaScript has strong support for functional style and so our programs can be written with rich expressions. JavaScript 对函数式风格有很强的支持,所以我们的程序可以用丰富的表达式来编写。 Program semantics are undisturbed by intermediate assignments like
arr
and syntax boilerplate like if
, else
, return
, and {...}
lying about.程序语义不受中间赋值(如
arr
和语法样板(如if
、 else
、 return
和{...}
干扰。
const countdown = n => n < 1 ? [] : [ n, ...countdown(n - 1) ] console.log(countdown(5))
[5,4,3,2,1]
This works because arr
is actually declared as an array.这是有效的,因为
arr
实际上被声明为一个数组。 This is because when arr is declared it is declared as the output of countdown(n -1)
.这是因为在声明 arr 时,它被声明为
countdown(n -1)
的输出。 Since countdown
has an exit condition that returns a new array []
which will eventually be reached because n
is decreasing every time its called.由于
countdown
有一个退出条件,它返回一个新的数组[]
,它最终会被到达,因为每次调用n
都会减少。 This is a basic example of recursion, a goog way to find out how it works is to step through the code in you mind or a debugger.这是递归的一个基本示例,找出它是如何工作的一种goog 方法是单步执行您脑海中的代码或调试器。
According to its definition, the function countdown
satisfies the equations根据其定义,函数
countdown
满足方程
.....
countdown(-2) = []
countdown(-1) = []
countdown(0) = []
countdown(1) = { const arr = countdown(0);
arr.unshift(1);
return arr; }
= countdown(0).unshift(1); // countdown(0)=[]
= [].unshift(1);
= [1]
countdown(2) = countdown(1).unshift(2); // countdown(1)=[1]
= [1].unshift(2);
= [2,1]
countdown(3) = countdown(2).unshift(3); // countdown(2)=[2,1]
= [2,1].unshift(3);
= [3,2,1]
.....
so actually everything is defined quite alright.所以实际上一切都定义得很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.