在学习时看到了一个面试题数组扁平化,模拟ES6的flat的效果编写。我也试试写了一下。确实还是有点难度。再次分享一下。
解题思路比较简单
1. 如果number传递有效参数的话,按照number参数控制扁平化次数
2. 每次扁平化循环也就是那个for循环。temp为需要扁平化数组, 如果没有到达扁平化层级需要清空result。
3. 如果number为Infinity的话就是将所有数组扁平化。所以有个判断扁平化数组是否都是非数组
// 这个可以 用Array.isArray替代
function isArray(target) {
const match = arguments.callee.name.match(/^is(?<type>.+)/i);
const type = match.groups.type ? match.groups.type : "";
return Object.prototype.toString.call(target) === `[object ${type}]`;
}
Array.prototype.flatten = function (number) {
// 判断扁平化层级参数是否合法
if (!Number(number) || number === 0) return this;
// 默认参数值
number = Number(number) || 1;
let result = [],
temp = [...this],
index = 0;
// 如果扁平化层级循环或者number是Infinity就是全部扁平
while ((index = index + 1) <= number || number === Infinity) {
for (let i = 0, length = temp.length; i < length; i++) {
const value = temp[i];
let values = isArray(value) ? value : [value];
result = [...result, ...values];
}
temp = [...result];
// 如果没有数组可以扁平化了就跳出循环
if (result.every((item) => !isArray(item))) {
break;
}
// 如果没有到扁平化层级 清空result 继续通过temp的数组循环扁平化
if (index !== number) result = [];
}
temp = null;
return result;
};
执行结果:
var arr = [1, [2, 3, [8]], [4, [5, 6, [7]]]];
console.log(arr.flatten("1")); // [1,[2,3,[8]],[4,[5,6,[7]]]]
console.log(arr.flatten(0)); // [1,[2,3,[8]],[4,[5,6,[7]]]]
console.log(arr.flatten()); // [ 1, 2, 3, [ 8 ], 4, [ 5, 6, [ 7 ] ] ]
console.log(arr.flatten(2)); // [1,2,3,8,4,5,6,[7]]
console.log(arr.flatten(3)); // [1,2,3,8,4,5,6,7]
console.log(arr.flatten(Infinity)); // [1,2,3,8,4,5,6,7]
仔细发现这个算法还是有提升的空间的。有很多没有必要循环的数组项。