数组扁平化的8种方案
数组扁平化是一个多层嵌套的数组(多维数组)转换为只有一层的数组(一维数组)的过程。在面试过程中是一道高频热点题目,开发过程中也会偶尔使用的
现在有这么一个数组
const arr = [1, 2, [3, [4, 5]], 6, [7, 8]]; 复制代码
实现一个函数flatten
将其扁平化
flat
直接调用 ES6 中的 flat 方法,可以直接实现数组扁平化,这是一个官方提供的API
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
使用方式:
var newArray = arr.flat([depth]); 复制代码
depth: 指定要提取嵌套数组的结构深度,不指定时默认值为 1。指定为Infinity
时则无论层都会扁平化为一层
arr.flat(Infinity) 复制代码
⚠️:flat()
方法会移除数组中的空项
const arr = [1,,[3,4]]; arr.flat(Infinity); // [1, 3, 4] 复制代码
普通递归
递归应该是最先想到的实现方式之一,递归总是可以朴实无华的解决很多问题????
const flatten = (arr) => { let res = []; for (let i = 0; i < arr.length; i++) { const item = arr[i]; if (Array.isArray(item)) { // 如果是数组 res = res.concat(...flatten(item)); } else { // 非数组 直接push res.push(item); } } return res; }; 复制代码
上述就是通过循环递归的方式,一项一项地去遍历,如果每一项还是一个数组,那么就继续往下遍历,利用递归程序的方法,来实现数组的每一项的连接
递归 + reduce
使用reduce
来替换普通递归中冗余的判断
const flatten = (arr) => { return arr.reduce((res, item) => { return Array.isArray(item) ? res.concat(...flatten(item)) : res.concat(item) }, []); }; 复制代码
代码整体简洁很多,简化了for
循环和if
条件判断,但是整体思路和简单递归保持一致
while + some
const flatten = (arr) => { while (arr.some((item) => Array.isArray(item))) { arr = [].concat(...arr); } return arr; }; 复制代码
整体思路:通过while
进行不断循环,结束条件为整个数组变成一维数组,只要存在多维数组则循环条件就一直成立
some
函数用于检测是否存在多维数组
while
内部用于不断的一层一层扁平化数据
整个while
循环结束,数组就是我们想要的一维数组
while + 堆栈
核心流程参考代码中注释
const flatten = (arr) => { const stack = [...arr]; const res = []; while (stack.length) { // 使用 pop 从 stack 中取出并移除值 const next = stack.pop(); if (Array.isArray(next)) { // 使用 push 送回内层数组中的元素,不会改动原始输入 stack.push(...next); } else { res.push(next); } } // 反转恢复原数组的顺序 return res.reverse(); }; 复制代码
toString + split
将数组toString
const str = arr.toString(); // 1,2,3,4,5,32,6,7,8 复制代码
将得到的字符串split
分割为数组,以,
分割
str.split(','); // ['1', '2', '3', '4', '5', '32', '6', '7', '8'] 复制代码
简历的两个API便可以实现数组扁平化
Generator
利用Generator
特性实现
const flatten = function* (arr) { for (const item of arr) { if (Array.isArray(item)) { yield* flatten(item); } else { yield item; } } }; console.log([...flatten(arr)]); 复制代码
Reg + JSON
const flatten = (arr) => { let str = JSON.stringify(arr); str = str.replace(/(\[|\])/g, ''); str = '[' + str + ']'; return JSON.parse(str); }; 复制代码
整体思路:
首先将数组序列化,得到一个字符串
利用正则将序列化后的字符串中的
[
和]
全部替换手动拼接
[]
,将其反序列化之后便是扁平化后的数组
作者:Nordon
链接:https://juejin.cn/post/7017694540693782541