我目前正在研究函数式编程技术。有关于这个问题的主题,,特别是关于java ,但没有关于JS。
我想要创建一个递归函数,它可以首先,计数直到我决定的极限,从我表示的数字开始,然后在达到极限时开始计数。我已经可以用for循环来完成这个任务了,但是感觉就像硬编码的,因为我提供了循环中的数字.。
基本上是这样的:
counter(0,10);
// 0, 1, 2, 3 ... 10, 9, 8... 0以下是我的想法:
counter = (number, limit) => {
limit !=== 0
if ( number = limit ) {
counter(number -1, limit -1)
console.log(number)
} else if ( number < limit ) {
counter(number + 1, limit + 1)
}
}这背后的想法是,如果数字低于上限计数向上,,如果它们相等,将每个参数减少1,以继续满足第一个if条件。
当我在v8上运行这个命令时,它给出了一个rangeError“达到的最大堆栈大小”.
而且,这不应该是一个无限循环。
循环版本:
for (let i = 0; i < 11; i++ ) { console.log(i) }
for (let i = 9; i < 11 && i > -1; i--) { console.log(i) }发布于 2021-01-28 09:57:08
您不需要循环返回或减少值,就像当您到达大小写(停止递归的东西)时,您将跳回包含前一个value的调用函数。
counter(0, 10) // logs: 0
| ^
| | (returns back to)
|---> counter(1, 10) // logs: 1
| ^
| | (returns back to)
|---> counter(2, 10) // logs: 2 <---
| | (returns back to)
| |
........ ---> counter(10, 10) // logs: 10 - base casecounter()的每个调用都会再次调用计数器(在上面的图中显示了子counter调用),然后这些调用将打印它们当前的value。到达基大小写时,打印当前值并返回,这将使您将控制传递回调用函数。我的意思是,当您调用一个函数时,该函数将运行。函数完成后,代码从函数最初调用的位置返回:
function bar() {
console.log("bar");
}
console.log("foo"):
bar(); // call the function makes the code execution jump up into `bar` function. When that completes, our code execution jumps back to the next line, which logs "baz"
console.log("baz");
在我们的counter()示例中,调用子counter()函数的位置是其父counter函数,当子函数完成执行(返回)时,我们跳过(传递控制)到其子函数。一旦控制权被传回。对于调用函数(即上面图表中的父函数),您可以再次记录value,因为它包含以前的value值。
function counter(value, limit) {
if(value === limit) {
console.log(value);
} else {
console.log(value); // on the way down / going deeper (increment)
counter(value+1, limit);
console.log(value); // on the way up / coming up from the depths (decrement)
}
}
counter(0,10);
// 0, 1, 2, 3 ... 10, 9, 8... 0
发布于 2021-01-28 16:56:21
递归是一种功能继承,因此将它与函数样式一起使用会产生最好的结果。这意味着避免诸如突变,可变的重新分配,以及其他副作用。
如果开始,
a,大于stop,b,我们已经达到了基本情况。返回空结果时,[]a小于或等于b。如果[a]a等于b,则返回单例结果,即山的“峰值”,则b a小于b。在子问题的a上重新查找a + 1, b并附加/预置结果。
这是一个纯函数表达式,下面的注释与上面的编号解释相匹配-
const uppendown = (a, b) =>
a > b
? [] // #1
: a == b
? [ a ] // #2
: [ a, ...uppendown(a + 1, b), a ] // #3
const ex1 =
uppendown(0, 10)
const ex2 =
uppendown(3,7)
const ex3 =
uppendown(9,7)
console.log(JSON.stringify(ex1))
// [0,1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1,0]
console.log(JSON.stringify(ex2))
// [3,4,5,6,7,6,5,4,3]
console.log(JSON.stringify(ex3))
// []
uppenDown(3,7)
= [ 3, ...uppendDown(3 + 1, 7), 3 ] // #3
= [ 3, 4, ...uppendDown(4 + 1, 7), 4, 3 ] // #3
= [ 3, 4, 5, ...uppendDown(5 + 1, 7), 5, 4, 3 ] // #3
= [ 3, 4, 5, 6, ...uppendDown(6 + 1, 7), 6, 5, 4, 3 ] // #2
= [ 3, 4, 5, 6, 7, 6, 5, 4, 3 ]uppendown(9,7) // #1
= []如果出于某些任意的原因,您不喜欢链接函数样式三元表达式,则可以将它们转换为命令式样式if语句-
function uppendown (a, b)
{ if (a > b)
return [] // #1
else if (a == b)
return [ a ] // #2
else
return [ a, ...uppendown(a + 1, b), a ] // #3
}
const ex1 =
uppendown(0, 10)
const ex2 =
uppendown(3,7)
const ex3 =
uppendown(9,7)
console.log(JSON.stringify(ex1))
// [0,1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1,0]
console.log(JSON.stringify(ex2))
// [3,4,5,6,7,6,5,4,3]
console.log(JSON.stringify(ex3))
// []
如果希望逐个显示数字而不是返回数组,则可以使用JavaScript的生成器。注意每个程序变体之间惊人的相似-
function* uppendown (a, b)
{ if (a > b)
return // #1
else if (a == b)
yield a // #2
else
( yield a // #3
, yield *uppendown(a + 1, b) //
, yield a //
)
}
for (const x of uppendown(3, 7))
console.log(x)
// 3
// 4
// 5
// 6
// 7
// 6
// 5
// 4
// 3
发布于 2021-01-28 11:15:02
像这样吗?
console.clear();
{
"use strict"
// Curry function
const nextStepInit = start => max => {
let increment = 1;
let counter = start;
return () => {
counter += increment;
if (counter >= max) {
increment = -increment;
return max;
}
if (counter <= start) {
return start;
}
return counter;
}
}
// this is a function, because nextStep(start)(max) returns a function
const nextStep = nextStepInit(0)(10)
const output = result => document.getElementById('output').value = result
const onClick = () => output(nextStep())
output(0)
document.getElementById('next-step').addEventListener('click', onClick)
}<button id="next-step">Next Step</button><br>
<input id="output" disabled/>
https://stackoverflow.com/questions/65934524
复制相似问题