前端flat函数多种实现

259 阅读2分钟

本文已参与「 新人创作礼 」活动,一起开启掘金创作之路

关于如何进行图片优化 - 适合的才是最好的

我们先回顾下昨天的一个问题,数组Flat的方式。

我们先列一个混合深度数组。

let array = [1,4,5,6,73,2,8,99,3,44,[1,3,65,[2,5,1],[3,6,77]]];

对于这个数组,我们该如何让其扁平化呢?

第一个写法是

let flattens = array => array.toString().split(",").map(item=>+item);

flattens(array) //[1, 4, 5, 6, 73, 2, 8, 99, 3, 44, 1, 3, 65, 2, 5, 1, 3, 6, 77]

这个方法利用就是toString去除维度,并String化,然后通过+"str" ,进行数值转化。

如果上面这个数组我们应用数组自带的Flat方法呢 ?

array.flat()//(15) [1, 4, 5, 6, 73, 2, 8, 99, 3, 44, 1, 3, 65, Array(3), Array(3)]
末尾是65,正好缺省flat的depth为1 // 等同于  array.flat(1)
array.flat(2)//[1, 4, 5, 6, 73, 2, 8, 99, 3, 44, 1, 3, 65, 2, 5, 1, 3, 6, 77]

如果我们手动实现一个呢 ?

Array.prototype.newflat = function (deep = 1) {
  return this.reduce((pre , cur)=>{
    return pre.concat(cur)
  },[])
}

这个demo貌似只能deep1层,扁平化没法深入。

Array.prototype.deepflat = function (deep = 1) {
  let results= [];
  (function flat (array , deep){
    for(let item of array) {
      if (Array.isArray(item) && deep > 0) {
        flat(item, deep - 1);
      } else {
        results.push(item)
      }
    }
  })(array , deep)
  return results;
}

array.deepflat(2)  //就能够深入多次

这样的代码看起来是不是感觉挺绕的。那有没有更好的方法呢 ?

Array.prototype.stackflat = function () {
  let stack = [...this];
  let results= [];
  while (stack.length > 0){
    let current = stack.pop();
    if ( Array.isArray(current) ) {
      stack.push(...current)
    } else {
      results.push( current )
    }
  }
  return results.reverse();
}

这个其实比较好的理解,只是看起来比较繁琐。

那是不是有比较时髦的方法 ?

let flat = function * ( _arr ) {
  for (let i = 0, j = _arr.length; i <j;i++) {
  	let item = _arr[i];
    if (item instanceof Array) {
    	yield* flat(item)
    } else {
    	yield item;
    }
  }
}

这个看来就比较高级,也是曾经比较喜欢生成器函数方法。

let temp = []
for (let l of flat(array)) {
  if (l.constructor !== flat.prototype.constructor){
  	temp.push(l);
  } else {
    console.log ( l.constructor )
  }
}
console.log (temp)

这个代码的复杂度,其掌握程度的细节也是比较多。

1.熟练使用生成器函数。

2.在遍历的时候还要判断item是否为生成器的类型。

就这样了,到达重点的方法很多,但是在业务中,最后还是使用通俗易通的,最后不要去写无限while、递归,很容易跑挂。这些要么交给内置函数 & 函数包来处理。画蛇添足会让业务的维护难上加难。