JavaScript 数组扁平化怎么写

正文内容

大家在日常做网页开发时,肯定遇见过这种情况:后端接口返回的数据里,会嵌套好几层数组,比如把“水果、蔬菜、肉类”三类食材各分成几小类,最后打包成一个大数组。可如果我们要把所有食材都列成平平整整的一维数组,就得用到“数组扁平化”——简单说就是把嵌套数组变成没有嵌套的单层数组。这篇就用生活里的例子,一步步讲清楚怎么用JavaScript实现它。

---

JavaScript 数组扁平化怎么写

先搞懂:为啥需要数组扁平化?

举个买菜的例子:你手机里的买菜APP,把“蔬菜类”“水果类”“肉类”存在三个小篮子(子数组)里,再把这三个小篮子装成一个大袋子(外层数组)。如果你想直接拿到所有“番茄、苹果、猪肉”这种单个食材,就得把袋子里的三个小篮子都倒出来,变成一整堆食材,这就是数组扁平化——把嵌套的数组“倒成单层”。

比如代码里的嵌套数组是:const food = [['番茄', '黄瓜'], ['苹果', '香蕉'], ['猪肉', '牛肉']],扁平化后要变成:['番茄', '黄瓜', '苹果', '香蕉', '猪肉', '牛肉']。

---

方法一:最偷懒的原生方法——`flat()`

JavaScript自带了专门处理扁平化的flat()方法,简直是给“懒程序员”量身定做的。它的用法特别简单,就像你不用自己动手倒篮子,直接让APP帮你把所有小篮子里的东西都倒出来就行。

默认的flat()只能处理一层嵌套,刚才的例子直接写food.flat()就得到想要的结果。如果遇到更深的嵌套,比如const deepArr = [1, [2, [3, [4]]]],想把所有层都展开,只要给flat()传个数字Infinity(代表“不管有多少层,全部展开”),写成deepArr.flat(Infinity),就能得到[1,2,3,4]。

这个方法的缺点是:如果数组里有“空项”(比如[1, , 2]),flat()会直接把空项删掉,变成[1,2]。如果业务里不能丢数据,这个方法就不太适用了。

---

方法二:适合复杂场景的手动写法——递归

如果想自己控制扁平化的过程,或者需要处理特殊情况(比如不能丢空项),可以用递归的方法——就像你自己动手倒篮子:先把大袋子里的每个小篮子拿出来,再把每个小篮子里的东西倒出来,遇到更小的篮子就再继续倒。

写个简单的函数:

`javascript

function flatten(arr) {

let result = [];

// 遍历数组里的每一项

for (let item of arr) {

// 如果这一项本身是数组,就递归调用自己处理它

if (Array.isArray(item)) {

result = result.concat(flatten(item));

} else {

// 不是数组的话,直接放进结果数组

result.push(item);

}

}

return result;

}

`

还是用刚才的deepArr测试,flatten(deepArr)就能得到[1,2,3,4]。这个方法的好处是灵活,比如你可以加个参数,指定只展开前几层嵌套,或者处理空项时直接放进结果数组。

---

方法三:数组加字符串的“取巧”写法

还有一种特别简单的取巧方法,适合临时用、嵌套不深的情况:把数组转成字符串,再把多余的括号去掉,最后转回数组。还是用刚才的food数组:先转成字符串"番茄,黄瓜,苹果,香蕉,猪肉,牛肉",去掉所有方括号,再用逗号转成数组就行。

代码就是:food.toString().split(','),就能得到目标数组。但这个方法只适合数组里全是字符串/数字的情况,如果嵌套数组里有对象或者布尔值(比如[true, [1, 2]]),转成字符串后会变成"true,1,2",最后得到['true','1','2'],类型就不对了,所以只适合简单场景。

实际开发里,大部分情况用flat()就够了;如果需要控制嵌套层数或者处理特殊数据,就用递归方法。多试几次,很快就能熟练掌握啦。

上一篇 Java 如何序列化对象