合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
[TOC] # 简介 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组。 举个例子,假设有个名为 flatten 的函数可以做到数组扁平化,效果就会如下: ~~~js var arr = [1, [2, [3, 4]]]; console.log(flatten(arr)) // [1, 2, 3, 4] ~~~ <br> <br> # flat ES6 为数组实例新增了`flat`方法,用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数组没有影响。 `flat`默认只会 “拉平” 一层,如果想要 “拉平” 多层的嵌套数组,需要给`flat`传递一个整数,表示想要拉平的层数。 ~~~ function flattenDeep(arr, deepLength){ return arr.flat(deelLength) } ~~~ <br> <br> # 递归 ~~~ function flatten1(arr) { var result = [] for (var i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { result.push.apply(result, flatten1(arr[i])) // 也可以使用 concat,但会产生新数组 // result = result.concat(flatten1(arr[i])) } else { result.push(arr[i]) } } return result } ~~~ # toString 如果数组的元素都是数字,那么我们可以考虑使用 toString 方法,因为: ~~~js [1, [2, [3, 4]]].toString() // "1,2,3,4" ~~~ <br> 调用 toString 方法,返回了一个逗号分隔的扁平的字符串,这时候再 split,然后转成数字就可以实现扁平化。 <br> 然而这种方法使用的场景却非常有限,**如果数组是 [1, '1', 2, '2'] 的话,这种方法就会产生错误的结果**。 ~~~ function flatten2(arr) { return arr.toString().split(',').map(function (item) { return +item }) } ~~~ <br> <br> # recude ~~~ function flatten3(arr) { return arr.reduce(function (prev, next) { // 可以简写成 // return prev.concat(Array.isArray(next) ? flatten3(next) : next) if (Array.isArray(next)) { return prev.concat(flatten3(next)) } else { return prev.concat(next) } }, []) } ~~~ <br> <br> # ... ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中: ~~~js var arr = [1, [2, [3, 4]]]; console.log([].concat(...arr)); // [1, 2, [3, 4]] ~~~ <br> 我们用这种方法只可以扁平一层,但是顺着这个方法一直思考,我们可以写出这样的方法: ~~~ function flatten4 (arr) { while(arr.some((item) => Array.isArray(item))) { arr = [].concat(...arr) } return arr } ~~~ <br> <br> # 参考资料 [JavaScript专题之数组扁平化](https://github.com/mqyqingfeng/Blog/issues/36#)