本文写于 2020 年 8 月 13 日
前两天在滴滴进行了前端实习面试,有几道题卡了一下。
一个数组里可能是基本数据类型,也可能是数组,数组里还能嵌套数组,例如:[1, 2, [4, [5, 7]], [[9]]]
。
请将数组扁平化,全部变成一维数组:[1, 2, 4, 5, 7, 9]
。
我第一次听题目的时候没听清,所以直接写了一次遍历,判断是否是数组,没有考虑数组嵌套的情况。
之后,便采用了递归的方法:
function flatArr(arr) {
let newArr = [];
if(arr.length >= 1) {
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
newArr.push(...flatArr(arr[i]));
} else {
newArr.push(arr[i]);
}
}
}
return newArr;
}
但是实际上,有更好的方法。
方法一:递归
不管怎么样,这种方法的核心思路就是递归。用 for
也好,用 while
也好,都是递归调用。
比如我们可以利用 reduce
来减少代码行数,这也是我最喜欢的一种方法。
function flatArr(arr) {
if(arr.length >= 1) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
}
代码的基础思路跟上面其实是一模一样的,但是却将代码缩减了至少一半!
或者说可以用 while
来进行:
function flatten(arr) {
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
但不推荐这么写,因为会对传入的参数进行修改。
方法二:偷巧
arr.toString()
返回的是一个字符串,这个字符串是以数组内的元素加上逗号生成的。
神奇的地方在于,当我们有一个数组为 [1, [2]]
的时候,他并不会变成 "1,[2]"
,而是会变成 "1,2"
。
所以我们就可以通过它来扁平化数组:
function flatArr(arr) {
if(arr.length >= 1) {
return arr.toString().split(‘,‘).map(item => Number.parseFloat(item))
}
}
这种方法不用 toString
用 join(‘,‘)
的效果是一样的。
Promise.all()
首先来看 Promise.all()
的用法:
const p1 = new Promise((resolve, reject) => {
if(/*成功*/) {
resolve(1);
} else {
reject(1);
}
});
const p2 = new Promise((resolve, reject) => {
if(/*成功*/) {
resolve(1);
} else {
reject(1);
}
});
const p3 = new Promise((resolve, reject) => {
if(/*成功*/) {
resolve(1);
} else {
reject(1);
}
});
Promise.all([p1, p2, p3]).then((results) => {
console.log(results);
}, (error) => {
console.log(error);
});
只有当三个 Promise 对象都成功时,才会执行 then 方法的第一个函数;只要有一个失败了,就会执行第二个函数。
对于 Promise.all()
来说,首先接收的是一个可迭代对象。
Promise
实例的数组或具有 Iterator
接口的对象;Promise
对象,则使用 Promise.resolve
转成 Promise
对象,也就意味着如果不是 Promise
对象,就让他变成完成状态的 Promise
;resolved
,返回值将组成一个数组传给回调;rejected
,返回值将直接传递给回调 all()
的返回值也是新的 Promise
对象。那我们就好实现了:
function promiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises) || !(typeof promise === ‘string‘)) {
return reject(new TypeError(‘参数必须是一个可迭代对象,例如数组或者字符串‘));
}
let resolvedCounter = 0;
let promiseNum = promises.length;
let resolvedValues = new Array(promiseNum);
for (let i = 0; i < promiseNum; i++) {
Promise.resolve(promises[i]).then((value) => {
resolvedCounter++;
resolvedValues[i] = value;
if (resolvedCounter === promiseNum) {
return resolve(resolvedValues);
}
}, (reason) => {
return reject(reason);
})
}
})
}
(完)
原文:https://www.cnblogs.com/xhyccc/p/13495020.html