2017-04-27 171 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