数组扁平化方法 Array.prototype.flat()
也叫数组拍平、数组拉平、数组降维。
Array.prototype.flat() 用于将嵌套的数组“拉平”,变成一维的数组。
该方法返回一个新数组,对原数据没有影响。
- 不传参数时,默认“拉平”一层,可以传入一个整数,表示想要“拉平”的层数。
- 传入 <=0 的整数将返回原数组,不“拉平”。
- Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组。
- 如果原数组有空位,Array.prototype.flat() 会跳过空位。
代码示例:
- const arr = [1,[2,3],[4,[5,[6]],7]];
-
- // 不传参数时,默认“拉平”一层
- arr.flat()
- // [1,2,3,4,[5,[6]],7];
-
- // 传入一个整数参数,整数即“拉平”的层数
- arr.flat(2)
- // [1,2,3,4,5,[6],7];
-
- // Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
- arr.flat(Infinity);
- // [1,2,3,4,5,6,7];
-
- // 传入 <=0 的整数将返回原数组,不“拉平”
- arr.flat(0);
- // [1,[2,3],[4,[5,[6]],7]]
- arr.flat(-6);
- // [1,[2,3],[4,[5,[6]],7]]
-
- // 如果原数组有空位,flat()方法会跳过空位
- [1,2,3,4,5,6,,].flat();
- // [1,2,3,4,5,6]
思路:实现一个有数组扁平化功能的 flat
函数,要做的就是在数组中找到是数组类型的元素,然后将他们展开。这就是实现数组拍平 flat
方法的关键思路。
遍历数组方案:
for 循环;for...of;for...in;forEach();entries();keys();values();reduce();map()
判断元素是数组方案:
instanceof;constructor;Object.prototype.toString;isArray
将数组的元素展开一层方案:
扩展运算符(…) ; concat;
apply:主要是利用 apply 在绑定作用域时,传入的第二个参数是一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。也就是在调用 apply 函数的过程中,会将传入的数组一个一个的传入到要执行的函数中,也就是相当对数组进行了一层的展开。
使用forEach+push递归实现:
- const arr = [1,[2,3],[4,[5,[6]],7]];
-
- function func(array) {
- let newArr = []
- const rec = (arr) => {
- arr.forEach(item => {
- if (!Array.isArray(item)) {
- newArr.push(item)
- } else {
- rec(item)
- }
- })
- }
- rec(array)
- return newArr
- }
- let res = func(arr)
- console.log(res) //[1,2,3,4,5,6,7]
使用for循环+concat实现:
- const arr = [1,[2,3],[4,[5,[6]],7]];
-
- function flatten(arr) {
- let result = [];
- for (let i = 0; i < arr.length; i++) {
- if (Array.isArray(arr[i])) {
- result = result.concat(flatten(arr[i]));
- } else {
- result = result.concat(arr[i])
- }
- }
- return result
- }
-
- console.log(flatten(arr));//[1,2,3,4,5,6,7]
增加参数控制扁平化深度,可以理解为手写flat()
方法:
- const arr = [1,[2,3],[4,[5,[6]],7]];
-
- //版本1:
- // forEach 遍历数组会自动跳过空元素
- const eachFlat = (arr = [], depth = 1) => {
- const result = [];
- (function flat(arr, depth) {
- arr.forEach((item) => {
- if (Array.isArray(item) && depth > 0) {
- flat(item, depth - 1)
- } else {
- result.push(item)
- }
- })
- })(arr, depth)
- return result;
- }
- console.log(eachFlat(arr,2))//[1,2,3,4,5,[6],7]
-
- //版本2:
- // for of 循环不能去除数组空位,需要手动去除
- const forFlat = (arr = [], depth = 1) => {
- const result = [];
- (function flat(arr, depth) {
- for (let item of arr) {
- if (Array.isArray(item) && depth > 0) {
- flat(item, depth - 1)
- } else {
- // 去除空元素,添加非 undefined 元素
- item !== void 0 && result.push(item);
- }
- }
- })(arr, depth)
- return result;
- }
- console.log(forFlat(arr,2))//[1,2,3,4,5,[6],7]
巧用reduce方法实现:
有关reduce方法的使用方法和具体细节请看我的这篇文章:戳我传送
- const arr = [1,[2,3],[4,[5,[6]],7]];
-
- const flatten = (arr, deep = 1) => {
- if (deep <= 0) return arr;
- return arr.reduce((res, curr) => res.concat(Array.isArray(curr) ? flatten(curr, deep - 1) : curr), [])
- }
-
- console.log(flatten(arr, Infinity));//[1,2,3,4,5,6,7]
-