2017-04-27 256 views
0

林求解codewars问题和IM肯定我已经得到了它的工作:Javascript递归函数没有返回值?

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

从本质上讲它应该找到一个“数字根”:

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

所以我其实得到的目的,而是在if声明无论什么原因,正确答案(其中即时观看调试运行,它输入的语句,它会说的返回值是正确的值。

但随后跳出if声明,并试图从主digital_root函数返回?

这是为什么呢?它不应该打出来的这个时候它击中if声明?林困惑,为什么它试图跳出if状态NT,然后尝试从digital_root返回任何内容,以便返回值最终未定义?

回答

3

你不会在else内返回任何东西。它应该是:

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

为什么?

digital_root应该返回一些东西。如果我们用一个数字号码来调用它,那么将执行if部分,并且由于我们从那个if返回,所以一切正常。但是如果我们提供一个由多个数字组成的数字,那么else部分就会被执行。现在,在else部分中,我们计算countdigital_root,但我们不使用该值(应该返回的值)。这使得它很容易理解的线以上可以被分成两行代码:

var result = digital_root(count); // get the digital root of count (may or may not call digital_root while calculating it, it's not owr concern) 
return result;     // return the result of that so it can be used from the caller of digital_root 
+0

废话,我不是超级习惯使用递归。我想......你能解释我们为什么要回来吗?是不是因为你想把“未来”的价值回归到现在呢? – msmith1114

+0

@ msmith1114查看解释!我希望这是有用的。 –

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

你应该返回相同的功能,而不是只是调用它以获得正确的调用堆栈

+0

你为什么使用循环和递归?在这种情况下,它几乎是一个或另一个 - 无论如何,这是无关紧要的;你的函数为'digital_root(123123123)'返回'9',但是应该返回'18' – naomik

+0

好的问题是为什么它返回undefined而不是一个值,我只是修正了代码 – subbu

+0

的递归部分,你的下一个问题请看这个链接什么是数字根 http://www.thonky.com/nine-hours-nine-persons-nine-doors/digital-root digital_root(123123123)= 9而不是18如果我得到了数字根概念right.if我错了我道歉,请分享您的观点在数字根 – subbu

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


使用减少

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

如果您打算使用实际的缩小功能,那么我会告诉您如何在此处执行此操作。首先,我们将制作一个toDigits函数,它接受一个整数,并返回其数字的数组。然后,我们将通过使用add减速器与空和初始化减少这些这些数字实现digitalRoot0

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