实现Array.prototype.flat 降维方法

349 阅读1分钟

flat 使用

const fruits = ['apple', ['banner', ['orange']]];
// 不传参数 默认降维一层
fruits.flat() // ['apple', 'banner ', ['orange']]  
// 传入一个整数 表示降维多少层
fruits.flat(int) 
// 传入 Infinity 关键字,无论多少层嵌套 都会转成一维数组
fruits.flat(Infinity) // ['apple', 'banner','orange'];
// 传入 <=0 的整数将返回原数组
fruits.flat(0)
fruits.flat(-10)
// 如果有空位 会忽略
const fruitsNew = ['apple', 'banner,', ['orange', '']]
fruitsNew.flat() // ['apple', 'banner', 'orange']

flat 特性总结

  • Array.prototype.flat 用于数组降维。该方法返回一个新数组,对原数据没影响
  • 传入 <=0返回原数据,不降维
  • Infinity 关键字作为参数。降维为一位数组
  • 如果原数组中有空位会跳过

实现

use stack

function flatStack(input) {
  const stack = [...input];
  const res = [];
  while (stack.length) {
    const next = stack.pop();
    if (Array.isArray(next)) {
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  return res.reverse();
}

递归

// 递归实现
function flat(input) {
  let res = [];
  for (let i = 0; i < input.length; i++) {
    const item = input[i];
    if (Array.isArray(item)) {
      res = res.concat(flat(item));
    } else {
      res.push(item);
    }
  }
  return res;
}

reduce 并添加降维层数

//reduce + concat + isArray + recursivity
function flatDeep(arr, d = 1) {
  return d > 0
    ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), [])
    : arr.slice();
}

Generator

// generator
function* flatGenarator(arr, num) {
  if (num === undefined) {
    num = 1;
  }
  for (const item of arr) {
    if (Array.isArray(item) && num > 0) {
      yield* flatGenarator(item, num - 1);
    } else {
      yield item;
    }
  }
}
// 调用 Generator 函数之后并不会执行 返回的也不是执行结果  
// 而是一个指向内部状态的指针对象,也就是遍历器对象(Iterator Object),
// 所以用扩展运算符展开
const newAry = [...flatGenarator(arr)]

可以自己动手把方法挂到Array的原型上