5种数组扁平化方法,让面试官对你刮目相看
5种数组扁平化方法,让面试官对你刮目相看
前记
其实一开始想写这个专栏很久了,因为面试中的“魔鬼面试官”总会这么说:“数组扁平化知道吗,你知道多少种就写多少种”,这个时候的我就开始抓耳挠腮了。这个专栏我想我会写一段时间,后续还会写到熟视无睹的浅拷贝和深拷贝、面试让你说出区别的防抖节流、神秘莫测的函数柯里化等等。
方法一:ES6 的 flat 方法
const arr = [1,[1,2],[1,[3]]]
console.log(arr.flat(Infinity))
这是数组自带的扁平化方法,flat的参数是说明需要展开几层,如果是Infinity无穷大的话,就是不管嵌套了几层,全部都会被展开 。想必这是大家一开始就想到的方法,毕竟那么好用的方法谁会不喜欢,但是如果你只知道这个的话,那不开心的肯定是面试官了。
方法二:递归
递归,用官方的话讲就是:在数学和计算机科学中,是指在函数的定义中使用函数本身的方法。通俗的话讲就是 自己调用自己。
const arr = [1, [2, [3, [4, 5]]], 6];
const array = [];
const fn = (arr) => {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
fn(arr[i]);
} else {
array.push(arr[i]);
}
}
};
fn(arr);
console.log(array);
最早接触使用扁平化递归的时候还是在刷蓝桥杯的题目,这应该也是面试中大家会写出来的方法,一整个全文背诵!
方法三:使用正则
const arr = [1,[1,2],[1,[3]]];
const res = JSON.stringify(arr).replace(/\[|\]/g, "");
const res2 = JSON.parse("[" + res + "]");
console.log(res2);
使用正则是我当时躺在床上想着有没有那种很难想到却很容易实现的方法,而正则是其实是我一直比较容易忘记的点,就那天却刚好想到这个点子:
- 首先是使用 JSON.stringify 把 arr 转为字符串
- 接着使用正则把字符串里面的 [ 和 ] 去掉
- 然后再拼接数组括号转为数组对象
方法四:使用 reduce
const arr = [1,[1,2],[1,[3]]];
const newArr = (arr) => {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? newArr(cur) : cur);
}, []);
};
console.log(newArr(arr), "reduce方法");
reduce 想必都是大家很喜欢的一个数组api,因为它相比于其他api,可玩性真的好很多。这里也用reduce来实现一下数组扁平化,其中也使用了 concat用于连接两个或多个数组,且该方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。
方法五:使用栈的思想实现 flat 函数
栈(stack),官方解释:又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。
function flat(arr) {
const newArr = [];
const stack = [].concat(arr);
while (stack.length !== 0) {
const val = stack.pop();
if (Array.isArray(val)) {
stack.push(...val);
} else {
newArr.unshift(val);
}
}
return newArr;
}
let arr = [1,[1,2],[1,[3]]];
console.log(flat(arr));
感觉用递归实现的需求用栈也能实现,就像树的三种遍历方式一样。实现的流程:
- 将数组元素拷贝至栈,直接赋值会改变原数组
- 如果栈不为空,则循环遍历
- 删除数组最后一个元素,并获取它
- 如果是数组再次入栈,并且展开了一层
- 如果不是数组就将其取出来放入结果数组中
待续
转载自:https://juejin.cn/post/7280051312690561060