ale*_*lex 3 javascript recursion while-loop
我while以这种方式使用:
while (value < -180 || value > 180) {
if (value < -180) {
value += 360
}
if (value > 180) {
value -= 360
}
}
Run Code Online (Sandbox Code Playgroud)
不过,我想使用递归函数而不是while. 我在谷歌上搜索但找不到任何东西。所以我想也许我可以在这里得到答案。
将显式循环转换为递归解决方案的“通用公式”是:
找出循环的“累加器”是什么。通常,循环将操作一个或两个值,这些值是循环的“结果”。
将累加器作为函数的参数。
很难概括如何用递归替换任何旧循环,但这可以用作一般准则:
对于具有以下形式的循环:
var a, b, c = ...;
while (condition) {
// Change a, b, c...
}
// Use a, b, c
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为:
function recursive(a, b, c...) {
// When the condition does *not* hold, end the recursion.
// Note that condition is negated relative to the while-loop.
if (!condition) {
// Base case.
return [a, b, c...];
} else {
// Change a, b, c...
// and recurse with the new values
return recursive(a', b', c'...);
}
}
Run Code Online (Sandbox Code Playgroud)
对于您的示例,这看起来像:
function recur(value) {
if (value > -180 || value < 180) {
return value; // Base case
} else if (value < -180) {
return recur(value + 360);
} else {
return recur(value - 360);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您希望再次循环,请递归,但请记住您需要返回递归的结果。对于想要结束循环的情况,返回累加器。请注意,每个执行分支都必须以 return 结束。一旦您丢弃递归结果(通过不返回它),数据就会丢失。
但请注意:
正如我在评论中提到的,递归并不是一个可以用来解决任何老问题的锤子;它应该是一个解决问题的工具。特别是当语言没有针对它进行优化时。对于小问题来说这可能没问题,但是当问题变得更大时,你可能会发现它会突然开始导致 StackOverflows。
在处理可变数据时,递归可能会变得困难且令人困惑。如果您的累加器是可变的(列表、映射或任何其他非基元),则您必须非常小心地设置所有内容。可以从递归的每个分支访问和更改相同的数据。如果你不小心,你的累加器就会以非常难以调试的方式被改变。如果您想走递归/函数式路径,我鼓励您研究像 Immutable.js 这样的库,或者像 Clojurescript 这样几乎专门处理不可变结构的语言。Clojurescript 编译成 JavaScript。