前端百题_竟然有五种方式实现flat方法
1 背景
const flatten = arr => arr.toString().split(',').map(item => +item);
const arr = [1, 2, [3, 4, [5, 6]]];
console.log(flatten(arr)); // [ 1, 2, 3, 4, 5, 6 ]不管多少层级都会展开为一个层级;
处理后的结果其实都是字符串,需要后续再转换为原来的类型。
2 flat基础
flat方法的用法如下所示:
const newArray = arr.flat([depth])
小试牛刀
const arr = [1, 2, [3, 4, [5, 6]]];
console.log(arr.flat(1)); // [ 1, 2, 3, 4, [ 5, 6 ] ]
console.log(arr.flat(2)); // [ 1, 2, 3, 4, 5, 6 ]3 实现
3.1 使用reduce和concat
利用reduce函数去依次处理每个数组中的元素;
利用concat将当前的数组元素(值或子数组)添加到结果数组中。
// 使用reduce和concat
Array.prototype.flat1 = function () {
return this.reduce((acc, val) => acc.concat(val), []);
}
3.2 使用reduce + concat + isArray + recursivity
利用reduce函数去依次处理每个数组中的元素;
利用concat将当前元素添加到结果数组中;
利用isArray判断当前数组中的元素是不是一个数组;
利用递归思想展开多层级的数组。
// 使用reduce + concat + isArray +recursivity
Array.prototype.flat2 = function (deep = 1) {
const flatDeep = (arr, deep = 1) => {
return deep > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, deep - 1) : val), []) : arr.slice();
}
return flatDeep(this, deep);
}
3.3 使用forEach + concat + isArray +recursivity
// 使用forEach + concat + isArray +recursivity
// forEach 遍历数组会自动跳过空元素
Array.prototype.flat3 = function (deep = 1) {
const result = [];
(function flat(arr, deep) {
arr.forEach((item) => {
if (Array.isArray(item) && deep > 0) {
flat(item, deep - 1);
} else {
result.push(item);
}
})
})(this, deep);
return result;
}
3.4 使用for of + concat + isArray +recursivity
// 使用for of + concat + isArray +recursivity
// for of 遍历数组会自动跳过空元素
Array.prototype.flat4 = function (deep = 1) {
const result = [];
(function flat(arr, deep) {
for(let item of arr) {
if (Array.isArray(item) && deep > 0) {
flat(item, deep - 1);
} else {
// 去除空元素,因为void 表达式返回的都是undefined,不适用undefined是因为undefined在局部变量会被重写
item !== void 0 && result.push(item);
}
}
})(this, deep);
return result;
}
3.5 使用堆栈stack
将要处理的数组放到一个栈中处理;
从栈顶取出元素,判断该元素类型,若为数组,则将该数组展开再放回栈顶;若为普通元素则将其放到结果中;
循环遍历,至到栈为空。
// 使用堆栈stack
Array.prototype.flat5 = function() {
const stack = [...this];
const result = [];
while (stack.length > 0) {
const next = stack.pop();
if (Array.isArray(next)) {
stack.push(...next);
} else {
result.push(next);
}
}
// 反转恢复原来顺序
return result.reverse();
}本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!