2016-06-08 137 views
-2

我是新來編寫遞歸函數,有點卡住了。我想不通,爲什麼這個功能輸出到控制檯兩次......看看:遞歸函數輸出雙重結果?

keyName = 'code'

// check, recursively, if an object contains an array 
let concatObject = function(obj) { 
    // get the keys of the parent object 
    let keys = Object.keys(obj); 
    // for each child object in the parent object 
    for (let i = 0; i < keys.length; i++) { 
     // get the current child 
     let key = keys[i]; 
     // get the keys of the current child 
     let intKeys = Object.keys(obj[key]); 
     // for each child object in the child object 
     for (let p = 0; p < intKeys.length; p++) { 
      // get the nested child 
      let intKey = intKeys[p]; 
      // if it's an array, repeat above steps by calling current function 
      if (!Array.isArray(obj[i][intKey])) { 
       // if it's not an array, get the value according to the passed keyName, checking for undefined 
       if (typeof obj[i][keyName] !== 'undefined') { 
        console.log(obj[i][keyName]); 
       } 
      } else { 
       console.log('FOUND ARRAY'); 
       concatObject(obj[i][intKey]); 
      } 
     } 
    } 
}; 

Annnd傳遞的對象(obj):

{ 
    code: "10", name: "Games", 
    subCategories: [ 
     {code: "10_34", name: "Action"}, 
     {code: "10_35", name: "Adventure"}, 
     {code: "10_36", name: "Arcade"}, 
     {code: "10_37", name: "Board"}, 
     {code: "10_38", name: "Card"}, 
     {code: "10_39", name: "Casino"}, 
     {code: "10_40", name: "Casual"}, 
     {code: "10_41", name: "Dice"}, 
     {code: "10_42", name: "Educational"}, 
     {code: "10_43", name: "Family"}, 
     {code: "10_44", name: "Kids"}, 
     {code: "10_45", name: "Music"}, 
     {code: "10_46", name: "Puzzle"}, 
     {code: "10_47", name: "Racing"}, 
     {code: "10_48", name: "Role Playing"}, 
     {code: "10_49", name: "Shooter"}, 
     {code: "10_50", name: "Simulation"}, 
     {code: "10_51", name: "Sports"}, 
     {code: "10_52", name: "Strategy"}, 
     {code: "10_53", name: "Trivia"}, 
     {code: "10_54", name: "Word"}, 
     {code: "10_55", name: "MMO"}, 
     {code: "10_57", name: "Gambling"}, 
     {code: "10_58", name: "Animals", animals: [ 
      {dog: "bark"}, 
      {cat: "meow"} 
     ]} 
    ] 
}, 

輸出,預計,聯合國(?)是:

10 
10 
FOUND ARRAY 
10_34 
10_34 
10_35 
10_35 
10_36 
10_36 
10_37 
10_37 
10_38 
10_38 
10_39 
10_39 
10_40 
10_40 
10_41 
10_41 
10_42 
10_42 
10_43 
10_43 
10_44 
10_44 
10_45 
10_45 
10_46 
10_46 
10_47 
10_47 
10_48 
10_48 
10_49 
10_49 
10_50 
10_50 
10_51 
10_51 
10_52 
10_52 
10_53 
10_53 
10_54 
10_54 
10_55 
10_55 
10_57 
10_57 
10_58 
10_58 
FOUND ARRAY 

過濾器工作(傳遞的keyName是'代碼',所以做不應該顯示嵌套的數組鍵名)但是對於我目前的實現,我在這裏使用的任何邏輯都會觸發兩次,而我不希望這樣!

幫助感謝,謝謝大家!

+0

我剛剛意識到我沒有展示我如何調用這個函數。我在switch語句中這樣做,如下所示: 'concatObject(obj);' 而且我100%確定我調用了一次(最初)。 – GrayedFox

+2

對於subCats數組中的每個對象,內部循環(var p)將循環兩次,一次用於對象中的每個鍵('code'和'name')。它將在每個循環中記錄「代碼」的值,因爲您已將其硬編碼爲keyName var的值。嘗試將console.log(obj [i] [keyName])更改爲console.log(obj [i] [intKey]),您的問題會更清晰一點 – Cmaddux

+0

預期的輸出是什麼? 'concat(obj)'沒有意義。 Concat obj與/與什麼? – naomik

回答

0

感謝@Cmaddux指出我邏輯上的缺陷。由於我遍歷每個對象中的每個鍵,所以我需要確保該函數僅在滿足正確條件時才起作用,即當傳遞的值keyName正在執行時。

更改我的IF條件,這解決了這個問題:

if ((typeof obj[i][keyName] !== 'undefined') && intKey === keyName)

教訓:永遠不要假設。我認爲這是遞歸堆棧中的一個時髦的東西,當時,人們認爲人爲錯誤佔上風。