2012-04-03 96 views
0

我有點迷路了,但如果有人能簡單地解釋一下爲什麼這段代碼能起作用,那會很棒!遞歸名稱

// Our array of messy words 
var capitals = ["berlin", "parIs", "MaDRiD"]; 

// Capitalize function 
function capitalize(word) { 
    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); 
} 

// Our recursive function 
function fixLetterCase(array, i) { 
    // Base case 
    if (i === array.length) { 
     return; 
    } 
    // Action 
    array[i] = capitalize(array[i]); 
    // Recursive case 
    return fixLetterCase(array, i + 1); 
} 

// Here is our function call 
fixLetterCase(capitals, 0); 

console.log(capitals); 
+0

你究竟在哪裏卡住了? – 2012-04-03 14:43:04

+0

我只是不明白所發生的一切。這很令人困惑 – Sam 2012-04-03 14:55:53

+0

但你知道這是遞歸。所以,你至少知道*某事*。那麼,代碼的哪一部分看起來對你來說很神奇?你需要什麼來更好地理解代碼? – 2012-04-03 14:56:58

回答

1

雖然我知道這不是一個問題的答案,我想這可能有助於看邏輯的非遞歸版本:

// Our array of messy words 
var capitals = ["berlin", "parIs", "MaDRiD"]; 

// Simple function to capitalize word 
function fixLetterCase(array) { 
    for(var i = 0; i < array.length; i++) { 
     array[i] = array[i].charAt(0).toUpperCase() + array[i].slice(1).toLowerCase(); 
    } 
} 

fixLetterCase(capitals); 
console.log(capitals);​ 

這裏的a working fiddle to play with.

1
function fixLetterCase(array, i) { 
    // At some point, this is true, so the algorithm stops 
    if (i === array.length) { return; } 
    // At this point, the function did not returned. The function logic continues. 

    // Replace the array key with a new value = the return value of captialize() 
    array[i] = capitalize(array[i]); 

    // i increments by one, and the function itself is called again. 
    return fixLetterCase(array, i + 1); 
} 

// Initialize the function, with starting offset ("counter") i=0 
fixLetterCase(capitals, 0); 
0

函數fixLetterCase被調用i等於零。當fixLetterCase第一次運行時,它會在數組中的第一個字上調用capitalize。在遞歸調用中,它使用1來遞增i,這意味着它將大寫數組中的下一個單詞。它將繼續這樣做直到它到達數組的末尾。

這就是爲什麼函數可以工作:需要大寫的單詞的索引每增加一次,在最後一次調用時,當索引等於數組長度時,'遞歸'結束。

請注意,這不是遞歸的典型用法,因爲遞歸調用沒有任何返回。還要注意,這可以寫得更直接一個for循環。

0

這確實不需要recursivly寫的,你可以做同樣的事情

// Our array of messy words 
var capitals = ["berlin", "parIs", "MaDRiD"]; 

// Capitalize function 
function capitalize(word) { 
    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); 
} 

// Our recursive function 
function fixLetterCase(array, i) { 

    // Action 
    array[i] = capitalize(array[i]); 
} 

// Here is our function call 
for(var i = 0; i < capitals.length; i++) 
{ 
    fixLetterCase(capitals, i); 
} 

console.log(capitals); 

遞歸部分只能通過資本迭代的話,當你到達數組末尾逃逸。希望像這樣閱讀會更清楚。

1
// Our recursive function 
function fixLetterCase(array) { 
    for (var i = 0, length = array.length; i < length; i++) { 
     array[i] = capitalize(array[i]); 
    } 
} 

可能是一個更好,更具可讀性,更高性能的解決方案。這種情況根本不需要遞歸,循環應該更有效。你不需要那麼多的函數調用,並且你不需要在每次函數調用時評估數組的長度。

1

我假設你談論遞歸部分。這實際上只是迭代數組的一種奇特方式。

按照慣例,你可以這樣做有for循環,下面的模式(原諒完全怪異的僞代碼,我自己總的發明):

for ([initialization]; [condition]; [modification]) 
    [function] 

遞歸,你可以做到這一點爲:

[function [initialization]] 
    if [!condition] 
    break 
    [function [modification]] 

我個人覺得在這種情況下遞歸版本沒有太大的好處,因爲它更少地道,因此不太明顯。並沒有提供性能優勢。