關於數組扁平化

針對這樣一個數組[3,[4,8,[9,1],3],[6,8],[2,10],5,7]想要將其展開,通常都會想到的是利用遞歸。 以下這樣一個方法:es6

function flatten(arr) {
    var newArr = [];
    arr.map(item => {
      if(Array.isArray(item)){
        newArr.push(...flatten(item))
      } else {
        newArr.push(item)
      }
    })
    return newArr
  }
複製代碼

可是這樣的方法在數組嵌套很是深的狀況下,函數遞歸調用時,調用層次太深,就會形成棧溢出。何爲棧溢出?數組

棧是一種後進先出的數據結構,堆棧也是採用這種結構管理內存,調用過程當中當最初的結果依賴於後面的計算處理,那麼後面的部分雖而後開始處理,卻先結束。當後續處理太多而且又依賴更後面的處理......(好比遞歸),便會一直壓棧,當空間所有用完,就會形成「堆棧溢出」。 更通俗一點就是向一個水桶裏裝水,等裝滿了以後再加水就溢出了。bash

這時候就應該換一種方法來解決這個問題,調用數組的toString方法或者join方法,將數組變爲字符串而後再用split分割還原爲數組能夠實現。數據結構

function flatten(arr) {
    return arr.toString().split(',').map(function(item) {
        return Number(item);
    })
} 
// 或者
function flatten(arr) {
    return arr.join(',').split(',').map(function(item) {
        return Number(item);
    })
}
複製代碼

可是該方法有一個缺點,就是會轉換數組中元素item的類型,須要進行類型轉換。 推薦使用es6的擴展運算符來實現數組扁平化。函數

function flatten(arr) {
    let stack = [...arr].reverse()
    let newArr = []
    while(stack.length){
      let o = stack.pop()
      if(Array.isArray(o)){
        stack.push(...o.reverse())
      } else {
        newArr.push(o)
      }
    }
    return newArr
  }
複製代碼
相關文章
相關標籤/搜索