[英]How can this recursive function for creating a range work?
從這個 SO-question中的選定答案中,這個非常巧妙的 function 創建了一個范圍從 1 到 i 的數組:
function range1(i){return i?range1(i-1).concat(i):[]}
它工作完美。 稱我為愚蠢,但我無法理解它是如何工作的。 假設我們有range1(5)
。 現在進入 function ,我們有i
,所以它返回自己的參數i-1
(4) 並將i
(5) 連接到它。 但在這里我被困住了: range1
怎么知道它與數組有關? 我會說在第一次運行后返回值(只要我們有i
,所以i!==0
)將是一個數字。 Number 沒有concat
方法。 有人可以解釋一下嗎? 我錯過了什么?
我擴展了這段代碼,因為我發現這種方式更容易理解。
function range1(i){
if (i != 0) {
return range1(i - 1).concat(i);
} else {
return [];
}
這個 function 背后的邏輯是,如果你想要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]
現在輸入 function,我們有 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]
。
注意:這個 function 可以很好地創建小 arrays,但是如果您需要一個大數組,那么創建數組並使用常規循環填充它會快得多。
遞歸的基本情況是[]
,因此遞歸的尾部將返回一個數組,其他步驟將連接到[]
(和前面的步驟)。
讓我們以 range1(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
function 總是返回一個數組。
它要么是一個空數組(對於 i == 0),要么是一個串聯數組。
在基本情況下range1
返回一個定義concat
的空數組。 當它展開時,范圍內的數字被添加到數組中。
直到我變成 0 為止,除了用 rediced 值調用 function 之外,什么都沒有,但是當它用 0 調用時,它返回 [] - 一個空數組,在之前的調用中應用了一個 concat 方法......它看起來像 range(0).concat(1 ) => [].concat(1) 所以 [1] 返回到上一個調用: [1].concat(2) 等等開始
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.