JS手写数组扁平化(flat)方法

时间:2025-01-20 19:38:12

方法介绍

数组扁平化方法 () 也叫数组拍平、数组拉平、数组降维。

() 用于将嵌套的数组“拉平”,变成一维的数组。

该方法返回一个新数组,对原数据没有影响。

  • 不传参数时,默认“拉平”一层,可以传入一个整数,表示想要“拉平”的层数。
  • 传入 <=0 的整数将返回原数组,不“拉平”。
  • Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组。
  • 如果原数组有空位,() 会跳过空位。

代码示例:

const arr = [1,[2,3],[4,[5,[6]],7]];

// 不传参数时,默认“拉平”一层
() 
// [1,2,3,4,[5,[6]],7];

// 传入一个整数参数,整数即“拉平”的层数
(2) 
// [1,2,3,4,5,[6],7];

// Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
(Infinity);
// [1,2,3,4,5,6,7];

// 传入 <=0 的整数将返回原数组,不“拉平”
(0);
// [1,[2,3],[4,[5,[6]],7]]
(-6);
// [1,[2,3],[4,[5,[6]],7]]

// 如果原数组有空位,flat()方法会跳过空位
[1,2,3,4,5,6,,].flat();
// [1,2,3,4,5,6]

 开始手写

思路:实现一个有数组扁平化功能的 flat 函数,要做的就是在数组中找到是数组类型的元素,然后将他们展开。这就是实现数组拍平 flat 方法的关键思路。

遍历数组方案:

for 循环;for...of;for...in;forEach();entries();keys();values();reduce();map()

判断元素是数组方案:

instanceof;constructor;;isArray

将数组的元素展开一层方案:

扩展运算符(…) ; concat;

apply:主要是利用 apply 在绑定作用域时,传入的第二个参数是一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。也就是在调用 apply 函数的过程中,会将传入的数组一个一个的传入到要执行的函数中,也就是相当对数组进行了一层的展开。

使用forEach+push递归实现:

const arr = [1,[2,3],[4,[5,[6]],7]];

function func(array) {
    let newArr = []
    const rec = (arr) => {
      (item => {
        if (!(item)) {
          (item)
        } else {
          rec(item)
        }
      })
    }
    rec(array)
    return newArr
  }
  let res = func(arr)
  (res) //[1,2,3,4,5,6,7]

 使用for循环+concat实现:

const arr = [1,[2,3],[4,[5,[6]],7]];

function flatten(arr) {
    let result = [];
    for (let i = 0; i < ; i++) {
      if ((arr[i])) {
        result = (flatten(arr[i]));
      } else {
      result = (arr[i])
      }
    }
    return result
  }
  
  (flatten(arr));//[1,2,3,4,5,6,7]

增加参数控制扁平化深度,可以理解为手写flat()方法:

const arr = [1,[2,3],[4,[5,[6]],7]];

//版本1:
// forEach 遍历数组会自动跳过空元素
const eachFlat = (arr = [], depth = 1) => {
    const result = []; 
    (function flat(arr, depth) {
      ((item) => {
        if ((item) && depth > 0) {
          flat(item, depth - 1)
        } else {
          (item)
        }
      })
    })(arr, depth)
    return result;
  }
  (eachFlat(arr,2))//[1,2,3,4,5,[6],7]
  
  //版本2:
  // for of 循环不能去除数组空位,需要手动去除
  const forFlat = (arr = [], depth = 1) => {
    const result = [];
    (function flat(arr, depth) {
      for (let item of arr) {
        if ((item) && depth > 0) {
          flat(item, depth - 1)
        } else {
          // 去除空元素,添加非 undefined 元素
          item !== void 0 && (item);
        }
      }
    })(arr, depth)
    return result;
  }
  (forFlat(arr,2))//[1,2,3,4,5,[6],7]

巧用reduce方法实现:

有关reduce方法的使用方法和具体细节请看我的这篇文章:戳我传送

const arr = [1,[2,3],[4,[5,[6]],7]];

const flatten = (arr, deep = 1) => {
    if (deep <= 0) return arr;
    return ((res, curr) => ((curr) ? flatten(curr, deep - 1) : curr), [])
}

(flatten(arr, Infinity));//[1,2,3,4,5,6,7]