2012-04-03 88 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]] 

我个人觉得在这种情况下递归版本没有太大的好处,因为它更少地道,因此不太明显。并没有提供性能优势。