2014-02-26 108 views
0

JSFiddle遞歸閉包

聯的小提琴表明,使用遞歸拉平任何尺寸的陣列(感謝用戶BERGIExlord他們在第一部分的幫助),並返回一個函數具有最高索引的數組。在我能夠得到一些有用的東西之前,我曾經嘗試過很多東西。我想澄清一些事情:

  1. 它是代碼的氣味,如果你有一個內部函數在一個明確接受參數的閉包內?例如:
  2. 爲什麼第二個腳本以最大調用堆棧大小超過錯誤結束?

-

return { 
     data: flatten(array), 
     rank: ranks.sort().reverse()[0] 
     //smelly code? 
} 

JS

//working code block 
    (function() { 
     function flattenAll(array) { 
      var ranks = []; 
      function flatten(array) { 
       var rank = 0; 
       var data = []; 
       $.each(array, function (index, item) { 
        //recursion here 
        typeof (item) !== 'object' ? data.push(item) : data = data.concat(flatten(item)); 
        rank++ 
       }); 
       ranks.push(rank); 
       return data; 
      }; 
      return { 
       data: flatten(array), 
       rank: ranks.sort().reverse()[0] 
      } 

     } 
     console.log(flattenAll([3, 4, [[[[[[4]]]]]], [[1, 4, 5]], [4]])); 
    })(); 
/****** second code block******************/ 
    (function() { 
     function flattenAll(array) { 
      var ranks = [], 
       //tried different approach for returning data 
       //this approach of setting returnData= data 
       //only grabs the last element in the array 
       returnData = []; 
      function flatten() { 
       var rank = 0; 
       var data = []; 
       $.each(array, function (index, item) { 
        //recursion here 
        $.isArray(item) ? data = flatten(item) : data.push(item); 
        rank++ 
       }); 
       ranks.push(rank); 
       returnData = data; 
       return data; 
      }; 
      return { 
       data: flatten(), //no parens here vs the first code block 
       rank: ranks.sort().reverse()[0] 
      } 

     } 
     console.log(flattenAll([3, 4, [[[[[[4]]]]]], [[1, 4, 5]], [4]])); 
    })(); 

是否有處理倒閉內處理遞歸有道?我不理解這裏發生的一切。

+0

按'排名'你的意思是數組長度? – georg

+0

@ thg435等級是陣列數組的真實數量。因此,一個包含數組的數組的排名爲2.包含數組數組的數組的排名爲3。 – wootscootinboogie

+0

這是該術語的正確用法,但不是代碼的用途。 – georg

回答

1

也許我失去了一些東西,但它看起來像你在第二個例子中看起來無限,因爲你反覆調用flatten(item)。平坦不存在爭論。這意味着你一直循環着同一個數組,這個數組就是你最初稱之爲flattenAll的數組,直到你超出了調用棧的限制。

0

對於代碼氣味的問題,您是否在談論對ranks.sort().reverse()[0]的調用?如果是這樣,並且你對此感覺不好,那麼你可以保持對maxRank的引用,而不是所有的等級。

這裏是你的第二個代碼塊:

(function() { 
    function flattenAll(array) { 
     var ranks = [], 
      //tried different approach for returning data 
      //this approach of setting returnData= data 
      //only grabs the last element in the array 
      returnData = []; 
     function flatten() { 
      var rank = 0; 
      var data = []; 
      $.each(array, function (index, item) { 
       //recursion here 
       $.isArray(item) ? data = flatten(item) : data.push(item); 
       rank++ 
      }); 
      ranks.push(rank); 
      returnData = data; 
      return data; 
     }; 
     return { 
      data: flatten(), //no parens here vs the first code block 
      rank: ranks.sort().reverse()[0] 
     } 

    } 
    console.log(flattenAll([3, 4, [[[[[[4]]]]]], [[1, 4, 5]], [4]])); 
})(); 

這裏只有一個array變量,它永遠不會改變。因此,您撥打flattenAll的原始數組與$.each中的始終使用的數組相同。那麼,這是否有道理,至於爲什麼你會得到一個調用堆棧異常? array指向外部array,因爲沒有隱藏它。