递归实现FizzBuzz时为何无法在递归函数内部正确反转数组
FizzBuzz递归实现问题解答
版本1无法正常运行的核心原因
Array.prototype.reverse()是原地反转数组的方法,不需要传参,且你每次要反转的results数组仅存储了当前num对应的1个元素,反转长度为1的数组不会产生任何效果,属于无效操作。- 你的递归拼接逻辑是「当前
num的计算结果」拼接「num-1到1的递归返回结果」,最终生成的数组天然是从大到小倒序排列的,每层递归的无效反转无法改变整体的排列顺序。 - 补充小问题:你没有声明
newResults变量,直接赋值会导致该变量泄漏为全局变量,存在副作用。
版本1的调整方案
不需要额外嵌套外层函数,只需要统一返回值类型、调整拼接顺序即可实现正序输出:
const fizzBuzzRecursive = num => { // 终止条件统一返回数组,和后续返回值类型保持一致 if (num === 1) { return ['1']; } let currentVal; if (num % 3 === 0 && num % 5 === 0) { currentVal = 'FizzBuzz'; } else if (num % 5 === 0) { currentVal = 'Buzz'; } else if (num % 3 === 0) { currentVal = 'Fizz'; } else { currentVal = '' + num; } // 先递归拿到 1~num-1 的正序数组,再把当前值拼到末尾,最终返回 1~num 的正序数组 return fizzBuzzRecursive(num - 1).concat(currentVal); } console.log(fizzBuzzRecursive(5)); // 打印 [ '1', '2', 'Fizz', '4', 'Buzz' ]
如果你一定要保留「从大到小拼接再反转」的逻辑,也可以简化成如下写法,不需要嵌套函数:
const fizzBuzzRecursive = num => { if (num === 1) { return ['1']; } let currentVal; if (num % 3 === 0 && num % 5 === 0) { currentVal = 'FizzBuzz'; } else if (num % 5 === 0) { currentVal = 'Buzz'; } else if (num % 3 === 0) { currentVal = 'Fizz'; } else { currentVal = '' + num; } return [currentVal].concat(fizzBuzzRecursive(num - 1)).reverse(); }
不过这种写法每次递归都要做一次全量反转,性能远不如第一种调整拼接顺序的方案,不推荐使用。
内容的提问来源于stack exchange,提问作者Detla888
相关产品推荐
相关产品推荐

