关于数组扁平化

针对这样一个数组[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
  }
复制代码
相关文章
相关标签/搜索