单手撸之ES2019-Array.flat

500 阅读1分钟

单手撸之前我们先看看官方的flat的用法:

let a = [1,2,[1,2,[1,2]]];
a.flat();//[1,2,1,2,[1,2]]
a.flat(2);//[1,2,1,2,1,2]
a.flat(Infinity);//[1,2,1,2,1,2]
console.log(a);//[1,2,[1,2,[1,2]]]

如果有empty slot 在数组中,将会过滤掉这些值。

const a = [1,2,,3];
a.flat();//[1,2,3]

特点:

  • 参数为Number类型,默认值为1

  • 参数为n就展开多维数组n次

  • 当参数为Infinity时,数组全部展开

  • 不改变原始数组

  • 过滤empty

理清楚了它的特性后,我们就开始撸起来,想实现展开n维数组之前我们是不是先实现展开一个维次的函数呢~

function flatOne(arr){
   return filter([].concat(...arr));
 }
 //去除empty值
 function filter(arr){
      return arr.filter((item,index)=>arr.hasOwnProperty(index))
  }
 let a = [1,2,[1,2];
 flatOne(a);//[1,2,1,2]

这里的empty简单说一下就是一个空的对象引用,想了解更多empty的说明(这里) 另外,它又是数组的方法,那扩展数组自定义方法,我选择在Array.prototype.myFlat上书写~

Array.prototype.myFlat = function(n=1){
   function flatOne(arr){
     return filter([].concat(...arr));
   }
  function filter(arr){
      return arr.filter((item,index)=>arr.hasOwnProperty(index))
  }
    //简单复制一下数组~
    let ret = this.slice();
    //如果是Infinity时
    if(!isFinite(n)){
        //判断是否还有数组
        while(ret.some(item=>Array.isArray(item))){
            ret = flatOne(ret)
        }
        return ret;
    }
    for(let i =0;i<n;i++){
        if(ret.some(item=>Array.isArray(item))){
            ret = flatOne(ret)
        }else{
            return filter(ret);
        }
    }
    
    return ret;
    
}

用法:

[1,2[1,2]].myFlat().myFlat(2).myFlat(Infinity);

结语:

其实这个小知识在面试的过程中还是经常遇到的,大家不妨想一想还有没有其他更简便的方法了~