javascript递归基础知识

时间:2015-11-18 22:53:09

标签: javascript recursion

我试图学习递归的概念,我通常在可能的情况下使用循环。任何人都可以在给出数组的情况下解释这段代码中发生的事情。

var set = [1, 2, 3, 4, 5];

function recurs(array) {

if (array.length === 0) {
    return 0;
}
else {
    return array.shift() + recurs(array);
}
  }
    console.log(recurs(set));

我理解if语句基本上给递归一个结束的机会。但是我对else语句中究竟发生了什么感到困惑,我理解.shift()函数删除了数组的第一个索引,但究竟是什么呢?我已经通过调试器,仍然无法理解它。正确的答案是15我只需要完全理解为什么。如果有人能为我分解,我们将不胜感激。

4 个答案:

答案 0 :(得分:2)

array.shift()删除数组的第一个元素,返回该元素。因此,该值将被添加到执行递归调用的结果中。然后递归调用与数组的剩余值做同样的事情。所以我们从

开始
recurse([1, 2, 3, 4, 5])

确实:

1 + recurse([2, 3, 4, 5])

变成

1 + 2 + recurse([3, 4, 5])

并最终进入:

1 + 2 + 3 + 4 + 5 + recurse([])

在最后一种情况下,if块只返回0,因此最终结果为:

1 + 2 + 3 + 4 + 5 + 0

答案 1 :(得分:1)

分解:

array:         return value (usually shift() + recurs():
[1,2,3,4,5]    1 + (next line, this is the recursive call)
[2,3,4,5]      2                   + "
[3,4,5]        3                   + "
[4,5]          4                   + "
[5]            5                   + "
[]             0 (array.Length==0)

所以,基本上结果变成:(1 +(2 +(3 +(4 +(5 +(0)))))) 每个()都是resurs函数的一个条目。

我建议在函数中添加console.log以查看传入的内容,并在返回之前存储recurs的返回值,并.log将其存储(给你)更好的视觉效果。)

答案 2 :(得分:1)

shift方法删除零点索引处的元素并将连续索引处的值向下移动,然后返回已删除的值。如果length属性为0,则返回undefined。

在您的示例中,如果数组的长度> 0您保留第一个元素,然后使用其余数组再次调用该方法。细分代码如下所示

recurs([1,2,3,4,5])
1 + recurs([2,3,4,5])
1 + 2 + recurs ([3,4,5])
1 + 2 + 3 + recurs([4,5])
1 + 2 + 3 + 4 + recurs ([5])
1 + 2 + 3 + 4 + 5 + recurs([])
1 + 2 + 3 + 4 + 5 + 0
15 (results)

答案 3 :(得分:1)

您可以在此处找到Array.prototype.shift上的MDN exlanation。从数组中删除第一个元素时,它也会返回删除的值(或未定义的),并更改数组的长度

从某种意义上说,你的功能与

非常相似
function sumElements(array) {
   if (!array || array.length === 0) {
       return 0; // full sum
   }
   // get the first value
   var firstValue = array[0];
   // remove it from the array
   array.splice(0, 1);
   return firstValue + sumElements(array); // get the next first value, which happens until the arrays length === 0
}

你的代码写得更清楚(你真的不需要那里的其他),将是

function recurse(array) {
    if (!array) || array.length === 0) {
        return 0;
    }
    var value = array.shift();
    return value + recurse(array);
}

你当然不需要得到这样的值,它只会在调试器中显示

  • 值已使用前一个数组索引
  • 进行了分配
  • array.length已更改,您现在正在使用递归中更改的数组

一个有趣的注意事项是,你发送到你的递归值的数组,在递归函数后将是一个空数组,但我确信在你的情况下可能没问题(不能判断它);)