Javascript递归函数没有返回值?

时间:2017-04-27 03:25:29

标签: javascript recursion

我解决了代码问题,我非常确定我已经开始工作了:

function digital_root(n) {
    // ...
    n = n.toString();
    if (n.length === 1) {
        return parseInt(n);
    } else {
        let count = 0;
        for (let i = 0; i < n.length; i++) {
            //console.log(parseInt(n[i]))
            count += parseInt(n[i]);
        }
        //console.log(count);
        digital_root(count);
    }
}

console.log(digital_root(942));

基本上它应该找到一个&#34;数字根&#34;:

  

数字根是数字中所有数字的递归和。   给定n,取n的数字之和。如果该值有两个   数字,以这种方式继续减少,直到一位数字为止   产生的。这仅适用于自然数。

所以我实际上在最后获得了正确的答案,但无论出于何种原因if语句(我正在观看调试器运行并且确实输入该语句,它会说返回值是正确的值。< / p>

然后它跳出if语句并尝试从主digital_root函数返回?

这是为什么?当它到达if声明时,它是否应该突破?我很困惑为什么它试图跳出if语句,然后尝试从digital_root返回任何内容,以便返回值最终未定义?

3 个答案:

答案 0 :(得分:3)

您未在else内返回任何内容。它应该是:

return digital_root(count);
^^^^^^^

<强>为什么吗

digital_root应该返回一些东西。如果我们用一位数字来称呼它,那么就会执行if部分,因为我们从if返回,所以一切正常。但是如果我们提供一个由多个数字组成的数字,那么else部分就会被执行。现在,在else部分,我们计算digital_root的{​​{1}},但我们不会使用该值(应返回的值)。上面的行可以分成两行代码,以便于理解:

count

答案 1 :(得分:1)

代码审核

我的评论是下面的代码评论

// javascript generally uses camelCase for function names
// so this should be digitalRoot, not digital_root
function digital_root(n) {
    // variable reassignment is generally frowned upon
    // it's somewhat silly to convert a number to a string if you're just going to parse it again
    n = n.toString();
    if (n.length === 1) {
        // you should always specify a radix when using parseInt
        return parseInt(n);
    } else {
        let count = 0;
        for (let i = 0; i < n.length; i++) {
            //console.log(parseInt(n[i]))
            count += parseInt(n[i]);
        }
        // why are you looping above but then using recursion here?
        // missing return keyword below
        digital_root(count);
    }
}

console.log(digital_root(942));

简单的递归解决方案

考虑到其中一些事项,让我们简化digitalRoot ...

的方法

const digitalRoot = n =>
  n < 10 ? n : digitalRoot(n % 10 + digitalRoot((n - n % 10) / 10))
  
console.log(digitalRoot(123))         //          => 6
console.log(digitalRoot(1234))        //       10 => 1
console.log(digitalRoot(12345))       //       15 => 6
console.log(digitalRoot(123456))      //       21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9

使用reduce

  

数字根是数字中所有数字的递归和。给定n,取n的数字之和。如果该值有两位数,则以这种方式继续减少,直到产生一位数字。这仅适用于自然数。

如果您打算使用实际的缩减功能,我会在这里向您展示如何做到这一点。首先,我们将创建一个带有整数的toDigits函数,并返回其数字的数组。然后,我们将使用digitalRoot缩减器使用空值add

初始化来减少那些数字,从而实现0

// toDigits :: Int -> [Int]
const toDigits = n =>
  n === 0 ? [] :  [...toDigits((n - n % 10) / 10), n % 10]

// add :: (Number, Number) -> Number
const add = (x,y) => x + y

// digitalRoot :: Int -> Int
const digitalRoot = n =>
  n < 10 ? n : digitalRoot(toDigits(n).reduce(add, 0))
      
console.log(digitalRoot(123))         //          => 6
console.log(digitalRoot(1234))        //       10 => 1
console.log(digitalRoot(12345))       //       15 => 6
console.log(digitalRoot(123456))      //       21 => 3
console.log(digitalRoot(99999999999)) // 99 => 18 => 9

答案 2 :(得分:0)

它是一个递归函数,代码应该有点像这样

function digital_root(n) {
    // ...
    n=n.toString();
    if(n.length === 1){
         return parseInt(n);
    }
    else
    {
    let count = 0;
    for(let i = 0; i<n.length;i++)
    {
    //console.log(parseInt(n[i]))
    count+=parseInt(n[i]);
    }
   //console.log(count);
   return digital_root(count);
   }
}

你应该返回相同的函数而不是只是调用它来获得正确的调用堆栈