带名字的递归

时间:2012-04-03 14:35:54

标签: javascript recursion

我总体上有点失落,但是如果有人可以请你简单解释为什么这段代码会很棒!

// 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);

6 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

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

可能是更好,更易读,更高效的解决方案。这种情况根本不需要递归,循环应该更有效。您不需要那么多函数调用,也不需要在每次函数调用时评估数组的长度。

答案 2 :(得分: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.

答案 3 :(得分:1)

我假设你在谈论递归部分。它实际上只是一种迭代阵列的异乎寻常的方式。

传统上你可以使用for循环来执行此操作,遵循模式(原谅完全奇怪的伪代码,我自己的总发明):

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

使用递归,你可以这样做:

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

我个人认为在这种情况下递归版本并没有太大的好处,因为它不那么惯用,因此不太明显它是如何工作的;它没有任何性能优势。

答案 4 :(得分:0)

调用函数fixLetterCasei等于零。当fixLetterCase第一次运行时,它会在数组中的第一个单词上调用capitalize。在递归调用中,它将i递增1,这意味着它将大写数组中的下一个单词。它将一直这样做,直到它到达数组的末尾。

这就是函数的工作原理:需要大写的单词的索引每次递增,在最后一次调用中,当索引等于数组的长度时,'递归'结束。

请注意,这不是递归的典型用法,因为递归调用没有返回任何内容。另请注意,这可以作为for循环更直接地编写。

答案 5 :(得分: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) { 

    // 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); 

递归部分只是遍历大写单词并在到达数组末尾时转义。希望这样读它会更清楚。