这个用于创建范围的递归函数如何工作
How can this recursive function for creating a range work?
从这个SO问题的选定答案中,这个非常巧妙的函数创建了一个范围从1到i的数组:
function range1(i){return i?range1(i-1).concat(i):[]}
它工作完美。说我愚蠢,但我就是无法理解它是如何工作的。假设我们有range1(5)
.现在进入函数,我们有 i
,所以它返回参数 i-1
(4( 并将i
(5( 连接到它。但在这里我陷入了困境:range1
怎么知道它与数组有关?我会说在第一次运行后返回值(只要我们有i
,所以i!==0
(将是一个数字。数字没有concat
方法。有人可以解释一下吗?我错过了什么?
我扩展了这段代码,因为我发现这样更容易理解。
function range1(i){
if (i != 0) {
return range1(i - 1).concat(i);
} else {
return [];
}
这个函数背后的逻辑是,如果你想要3
元素的列表(range(3)
(,你取2
元素的列表(range1(i - 1)
(,并在它的末尾添加3
.concat(i)
。除此之外,您只需要处理特殊情况,即range1(0)
是空数组[]
即可完成。
想象一下给range1(2)
打电话.自i != 0
年以来,我们得到
range(2) = range(1).concat(2)
range(1)
返回range(0).concat(1)
,给我们
range(2) = range(0).concat(1).concat(2)
那么,什么是range(0)
?自i == 0
以来,我们得到了我们需要的空数组([]
(!
range(2) = [].concat(1).concat(2) -> [1, 2]
现在进入函数,我们有 i, 所以它返回带有参数的自身 I-1 (4( 并连接 I (5(。
不,它不会自行返回。它所做的是调用自身,即递归,然后返回该调用的结果,最后一个元素连接起来。
所以,range1(5)
会调用range1(4)
,这会调用range1(3)
,依此类推。当它达到零时,它将停止调用并返回一个空数组。
range1(0)
返回[]
,所以range1(1)
返回[].concat(1)
[1]
,然后range1(2)
返回[1].concat(2)
[1,2]
,依此类推。当我们回到range1(5)
它返回[1,2,3,4].concat(5)
这是[1,2,3,4,5]
.
注意:此函数非常适合创建小数组,但是如果您需要一个大数组,则创建数组并使用常规循环填充它会快得多。
递归的基本情况是 []
,因此递归的尾部将返回一个数组,其他步骤将连接到[]
(和前面的步骤(。
让我们以范围 1(4( 为例:
range1(4) => range1(3).concat(4)
range1(3) => range1(2).concat(3)
range1(2) => range1(1).concat(2)
range1(1) => range1(0).concat(1)
range1(0) => []
现在取第一行,并将 range1(3( 替换为下一行的等效项。你得到这个:
range1(4) => range1(2).concat(3).concat(4)
继续替换 range1 引用,直到没有剩余引用。最终结果:
range1(4) => [].concat(1).concat(2).concat(3).concat(4)
range1
函数始终返回一个数组。
它要么是一个空数组(对于 i == 0(,要么是一个串联数组。
在基本情况下,range1
返回一个定义concat
的空数组。当它展开时,范围内的数字被添加到数组中。
直到我变成 0 除了使用重定向值调用函数之外,什么都不会发生,但是当它用 0 调用时,它会返回 [] - 上一次调用中的一个空数组应用了一个 concat 方法......看起来 range(0(.concat(1( => [].concat(1( 所以 [1] 返回到上一个调用: [1].concat(2( 等等开始
- Javascript:selenium Web驱动程序isDisplayed()不工作
- jQuery UI自动完成突然停止工作
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- JavaScript打印功能使日历停止工作
- Javascript.getHours()工作不正常
- 为什么这在IE中的工作方式与在Firefox中不同
- 视频HTML没有'无法在Internet Explorer 11上工作
- 扩展移相器按钮类不工作
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 正在尝试使用if和else添加类,但无法正常工作
- Jquery FadeIn FadeOut 只工作一次
- Foreach无法在Typescript中工作
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- JS可以在Chrome中工作,但不能在Firefox中工作
- ajaxToolkit PopupControlExtender不工作.过时的
- HTML标记在脚本标记中工作
- 在JavaScript中的类中,push和concat的工作方式有何不同