JS数组扁平化方法详解:flat、递归与while循环实现
本文汇总了JavaScript中实现数组扁平化的三种主流方案。首先解析ES10引入的flat()方法及其深度参数控制;其次介绍利用toString()转换字符串的冷门技巧;重点讲解递归思想,包括纯手写与结合reduce函数的精简写法;最后演示基于ES6解构语法与while循环的迭代实现,帮助开发者应对多层嵌套数组的处理需求。
前言
数组扁平化是前端开发中常见的面试题,本文旨在梳理几种主流的实现方式。该问题的核心在于处理多层嵌套结构,通常需要通过循环或递归来遍历所有层级的元素。本文将重点解析递归逻辑,并展示其他可行方案。
flat() 方法
最直接的方案是使用JavaScript内置的flat方法。该方法属于Array原型,用于将多维数组转换为一维数组,此功能在ECMAScript 2019 (ES10)标准中被正式引入。flat方法支持一个可选参数depth,用于控制扁平化的层级深度。
- 当不传递参数或传入
1时,方法默认仅扁平化数组的第一层嵌套。 - 若传入数字
n,则表示将数组扁平化至指定的n层深度。 - 如果传入
Infinity作为参数,无论嵌套层级多深,最终结果都会被完全扁平化为一维数组。
下面是一些示例
let arr = [1,[2,[3,[4,5]]]];
// 只会扁平化一层
console.log(arr.flat(1));//[1,2,[3,[4,5]]]
// 扁平化两层
console.log(arr.flat(2));//[1,2,3,[4,5]]
// 全部扁平化
console.log(arr.flat(Infinity));//[1,2,3,4,5]
toString()方法
这里分享一个技巧:数组的toString方法会将所有元素以逗号连接成字符串。由于逗号分隔天然打破了层级结构,因此toString方法能将任意深度的嵌套数组转化为逗号分隔的字符串形式,这为扁平化提供了一种非常规思路。
let arr = [1,[2,[3,[4,5]]]];
//toString方法变成字符串
console.log(arr.toString());//'1,2,3,4,5'
arr = arr.toString().split(",").map(function (item){
return +item;
})
递归
对于未知深度的嵌套数据,循环或递归是遍历所有元素的必要手段。尽管递归因频繁创建执行栈上下文而在性能上略逊于迭代,但其代码逻辑直观且易于理解,展现了编程的优雅性。
纯手写递归
let arr = [1,[2,[3,[4,5]]]];
function flatten(arr) {
//创建一个数组,接受扁平化的数组
let result = [];
for(let i=0,len=arr.length;i<len;i++){
// 如果子元素是数组
if(Array.isArray(arr[i])){
// 将 子元素扁平之后加入到结果数组里面
result = result.concat(flatten(arr[i]));
}else{
// 子元素不是数组就直接添加
result.push(arr[i]);
}
}
return result;
}
console.log(flatten(arr));//[1,2,3,4,5]
reduce方法进行递归(代码较少)
此处简要说明reduce函数的用法。reduce会遍历数组每个元素,执行回调函数。回调接收两个参数:累加器(上一次回调的返回值)和当前元素值。若提供初始值,则从第一个元素开始遍历;否则默认以第一个元素为初始值,从第二个元素开始。最终返回最后一次回调的结果。以下是reduce的基础示例
let arr = [1,2];
console.log(arr.reduce((sum,nowVal)=>sum+nowVal))// 3
console.log(arr.reduce((sum,nowVal)=>sum+nowVal,4))// 4
在理解reduce的基础上,我们来实现数组的递归扁平化
let arr = [1,[2,[3,[4,5]]]];
function flatten(arr){
// 和普通递归相同,这里只不过是缩减了代码,思想一致
return arr.reduce((result,nowValue)=>
Array.isArray(nowValue)?result.concat(flatten(nowValue)):result.concat(nowValue),[]);
}
console.log(flatten(arr));// [1,2,3,4,5]
while循环
尽管递归技术非常实用,但此处仍需介绍循环实现方式。本文涉及数组结构方法,JavaScript中的解构允许从数组或对象提取数据并赋值给变量。该特性由ES6(ECMAScript 2015)引入,显著提升了代码简洁性与可读性。此处仅举一例说明:
let arr = [1,2,3,[4,5]];
let [first,...rest]=arr;//first就是1,这里的rest就会存储剩下的元素[2,3,[4,5]]
接下来演示基于解构和循环的扁平化实现
let arr = [1,[2,[3,[4,5]]]];
function flatten(arr){
let result = [];
while(arr.length!=0){
// 将arr的第一个元素取出,剩下的存入rest数组中
let [first,...rest] = arr;
if(Array.isArray(first)){
//如果是数组,那么就将first进行解构将里面的元素逐一添加到arr中,
//相当于将first里面的元素降了一个层级,rest必须进行解构添加
// 否则将会将rest里面的元素层级提升
arr = [...first,...rest];
}else{
//如果第一个元素不是数组,就添加到结果数组中
result.push(first);
//这里相当与将第一个元素剔除,下次遍历取rest数组第一个元素
arr =[...rest];
}
}
return result;
}
console.log(flatten(arr));// [1,2,3,4,5]
结语
至此,关于JS数组扁平化的几种方法(递归、while循环、flat)已介绍完毕。如需了解更多相关内容,建议查阅本站过往文章或继续阅读后续系列。感谢支持!
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58
