方法介绍
数组扁平化方法 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]