Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
雄辩的JavaScript ch5-“;“你自己的循环”;解决方案(循环与递归)_Javascript_Loops_Recursion - Fatal编程技术网

雄辩的JavaScript ch5-“;“你自己的循环”;解决方案(循环与递归)

雄辩的JavaScript ch5-“;“你自己的循环”;解决方案(循环与递归),javascript,loops,recursion,Javascript,Loops,Recursion,我在第一次尝试时确实溢出了堆栈,但后来我在没有参数的情况下放入了return语句(请参见代码中的注释),结果成功了 任务: 编写一个高阶函数循环,提供类似于for循环语句的内容。它接受一个值、一个测试函数、一个更新函数和一个主体函数。每次迭代,它首先对当前循环值运行测试函数,如果返回false,则停止。然后调用body函数,给它当前值。最后,它调用update函数来创建一个新值,并从头开始 定义函数时,可以使用常规循环来执行实际循环 我没有使用循环。 图书解决方案 function loop(s

我在第一次尝试时确实溢出了堆栈,但后来我在没有参数的情况下放入了return语句(请参见代码中的注释),结果成功了

任务:

编写一个高阶函数循环,提供类似于for循环语句的内容。它接受一个值、一个测试函数、一个更新函数和一个主体函数。每次迭代,它首先对当前循环值运行测试函数,如果返回false,则停止。然后调用body函数,给它当前值。最后,它调用update函数来创建一个新值,并从头开始

定义函数时,可以使用常规循环来执行实际循环

我没有使用循环。

图书解决方案

function loop(start, test, update, body) {
   for (let value = start; test(value); value = update(value)) {
     body(value);
   }
 }

 loop(3, n => n > 0, n => n - 1, console.log);
 // → 3
 // → 2
 // → 1
我的解决方案(保留我的原始函数参数名称)

我是刚刚让控制台输出了同样的东西,还是我的解决方案在真实环境程序中也会做同样的事情


我问,因为我不确定我是否真的用递归解决了它,或者只是让控制台输出相同的东西。这将帮助我对自己感觉更好,因为我是一个noob JS学习者。谢谢!:)

是的,这是任务的正确递归实现。你并不是偶然得到正确的输出

但是,
else返回值
有点奇怪。我也会写

function loop(value, test, update, execute) {
  if (test(value)) {
    execute(value);
    return loop(update(value), test, update, execute);
  } // else stop
}


是的,这是任务的正确递归实现。你并不是偶然得到正确的输出

但是,
else返回值
有点奇怪。我也会写

function loop(value, test, update, execute) {
  if (test(value)) {
    execute(value);
    return loop(update(value), test, update, execute);
  } // else stop
}

初始值设定项 book解决方案创建一个
变量,并用start对其进行初始化。在您的情况下,当您传递第一个参数时,这会自动发生。到目前为止,这两种方法是等效的

试验
for
循环调用
test(value)
作为循环
test
。您的方法执行类似的操作,但是调用
test
是对递归的测试。到目前为止,这两种方法是等效的

循环块
for
循环调用
body(value)
。您的方法调用
execute(value)
。到目前为止,这两种方法是等效的

更新
在每次迭代后的循环中更新。在递归调用中传递
update(value)
时,代码中也会发生同样的情况。到目前为止,这两种方法是等效的

它们真的相等吗? 在算法上,是的。从技术上讲,不是。递归方法多次调用
函数
,并使用堆栈(内存)存储
函数
调用。如果
测试次数过多
,您的代码将崩溃。因此,您已经成功地实现了本书示例的递归版本(耶!),但在大多数情况下,您应该尽量避免递归。

Initializer book解决方案创建一个
变量,并用start对其进行初始化。在您的情况下,当您传递第一个参数时,这会自动发生。到目前为止,这两种方法是等效的

试验
for
循环调用
test(value)
作为循环
test
。您的方法执行类似的操作,但是调用
test
是对递归的测试。到目前为止,这两种方法是等效的

循环块
for
循环调用
body(value)
。您的方法调用
execute(value)
。到目前为止,这两种方法是等效的

更新
在每次迭代后的循环中更新。在递归调用中传递
update(value)
时,代码中也会发生同样的情况。到目前为止,这两种方法是等效的

它们真的相等吗?
在算法上,是的。从技术上讲,不是。递归方法多次调用
函数
,并使用堆栈(内存)存储
函数
调用。如果
测试次数过多
,您的代码将崩溃。因此,您已经成功地实现了本书示例的递归版本(耶!),但在大多数情况下,您应该尽量避免递归。

我不明白您所说的“使控制台输出相同”是什么意思。换句话说,我的解决方案是真正的解决方案,还是只是运气——正如您在其他评论中提到的那样。谢谢你,伙计,谢谢你!我不明白你所说的“使控制台输出相同的东西”是什么意思。换句话说——我的解决方案是真正的解决方案,还是只是运气——正如你在其他评论中提到的那样。谢谢你,伙计,谢谢你!
function loop(value, test, update, execute) {
  if (!test(value)) return; // stop
  execute(value);
  return loop(update(value), test, update, execute);
}