问题描述
我的大脑认为我应该使用.push()
而不是.unshift()
,但是freeCodeCamp和控制台表明这是正确的方法。我只是不明白如何使用.unshift()
将数字从10变为20,而使用.push()
将数字从20变为10;
我阅读代码的方式:
如果startNum
大于endNum
,则返回一个空数组。否则,请创建一个名为arr
的变量,并在每次代码运行时将当前startNum
的值加1,然后将其返回到数组中。
我在做什么错了?
function rangeOfNumbers(startNum,endNum) {
if (startNum > endNum) {
return [];
} else {
const arr = rangeOfNumbers(startNum + 1,endNum);
arr.unshift(startNum);
return arr;
}
}
console.log(rangeOfNumbers(10,20));
控制台:(11) [10,11,12,13,14,15,16,17,18,19,20]
解决方法
unshift
将一个元素插入数组的开头。
由于您是从startNum
到endNum
进行迭代,因此请考虑倒数第二个递归调用:
const arr = rangeOfNumbers(startNum + 1,endNum);
arr.unshift(startNum);
return arr;
其中startNum
为19,endNum
为20。递归调用返回一个数组,其中包含一个元素:[20]
。然后,您需要在适当的位置插入19
元素。
为此,您需要在开头插入19,以获取:
[19,20]
因此,在unshift
的开头插入19。
如果您改用push
,则从原始的[20]
您将获得:
[20,19] // 19 added to end
然后
[20,19,18] // 18 added to end
以此类推,顺序不正确。
如果在递归调用之前 插入元素,则可以使用push
。
function rangeOfNumbers(startNum,endNum,arr = []) {
arr.push(startNum);
if (startNum < endNum) {
rangeOfNumbers(startNum + 1,arr);
}
return arr;
}
console.log(rangeOfNumbers(10,20));
,
一种思考的方式是想象递归调用已经正常工作。因此rangeOfNumbers(11,20)
将产生[11,12,13,14,15,16,17,18,20]
。因此const arr = rangeOfNumbers(startNum + 1,endNum)
意味着arr
是[11,20]
。现在您有了startNum
和arr
,需要将它们结合起来。 push
将startNum
添加到末尾。 unshift
正确地将其添加到开头。
但是,当我们在这里时,我想提出一种更优雅的方式来表达相同的算法:
const rangeOfNumbers = (start,end) =>
start > end
? []
: [start,... rangeOfNumbers (start + 1,end)]
我们有一个条件表达式,而不是if-else
语句。而且,我们不会在此过程中变异像arr
这样的变量。我认为它也更清晰地表达了算法。当然,口味可能会有所不同,并且,如果您只是在学习JS,则可能涉及您尚未见过的语法。但是,如果您了解它,那么您可能会同意我的优雅。