JS-五种数组扁平化方法总结
问题抛出:对于[1, [1,2], [1,2,3]这样多层嵌套的数组,我们如何将其扁平化为[1, 1, 2, 1, 2, 3]这样的一维数组呢(数组降维):
1、ES6 的 flat()
先来简单看一下关于它的使用:
const arr = [1, [1,2], [1,2,3]] arr.flat(Infinity) // [1, 1, 2, 1, 2, 3]
note:
MDN:flat() 方法会按照一个可指定的深度(传入的参数)递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回
Array.prototype.flat() 特性总结:
-
用于将嵌套的数组扁平化,变成一维的数组。该方法返回一个新数组,对原数据没有影响。 不传参数时,默认扁平化一层,可以传入一个整数,表示想要扁平化的层数。 传入 <=0 的整数将返回原数组,不扁平化 Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组 如果原数组有空位,Array.prototype.flat() 会跳过空位。
方法虽好,但是使用这个方法前要先考虑一下兼容性问题哦!!!
我们来实现一个 flat 吧!!!
note:
MDN:reduce() 方法对数组中的每个元素执行一个由提供的reducer函数(升序执行),将其结果汇总为单个返回值
// 传入两个参数:数组arr 扁平化层数depth(默认是一层) function flat (arr, depth = 1) { return depth > 0 ? // 层数大于0才进行扁平化 arr.reduce((acc, cur) => { // acc:reducer 函数的返回值(累计器),cur:当前值(arr 中遍历到的当前元素值) if (Array.isArray(cur)) { // 当前值是 数组 return [...acc, ...flat(cur, depth - 1)]; // 递归执行 flat 函数,插入返回数组中 累计器的值后面 } return [...acc, cur]; // 当前值不是数组,直接插入返回数组中 累计器后面 }, []) : arr // 扁平化层数小于等于0,直接返回原数组 arr }
2、序列化后正则
const arr = [1, [1,2], [1,2,3]] const str = `[${JSON.stringify(arr).replace(/([|])/g, )}]` JSON.parse(str) // [1, 1, 2, 1, 2, 3]
3、递归
对于树状结构的数据,最直接的处理方式就是递归
const arr = [1, [1,2], [1,2,3]] function flat(arr) { let result = [] for (const item of arr) { item instanceof Array ? result = result.concat(flat(item)) : result.push(item) } return result } flat(arr) // [1, 1, 2, 1, 2, 3]
4、reduce()递归
const arr = [1, [1,2], [1,2,3]] function flat(arr) { return arr.reduce((acc, cur) => { return acc.concat(cur instanceof Array ? flat(cur) : cur) }, []) } // 或者 function flat(arr) { return Array.isArray(arr) ? arr.reduce( (acc, cur) => [...acc, ...flattenDeep(cur)] , []) : [arr] } flat(arr) // [1, 1, 2, 1, 2, 3]
5、迭代+展开运算符
// 每次while都会合并一层的元素,这里第一次合并结果为[1, 1, 2, 1, 2, 3, [4,4,4]] // 然后arr.some判定数组中是否存在数组,因为存在[4,4,4],继续进入第二次循环进行合并 let arr = [1, [1,2], [1,2,3,[4,4,4]]] while (arr.some(Array.isArray)) { arr = [].concat(...arr); } console.log(arr) // [1, 1, 2, 1, 2, 3, 4, 4, 4]
上一篇:
IDEA上Java项目控制台中文乱码