滴滴实习面试题

滴滴实习面试题

本文写于 2020 年 8 月 13 日

前两天在滴滴进行了前端实习面试,有几道题卡了一下。

1 扁平化数组

一个数组里可能是基本数据类型,也可能是数组,数组里还能嵌套数组,例如:[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))
  }
}

这种方法不用 toStringjoin(',') 的效果是一样的。

2 实现 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() 来说,首先接收的是一个可迭代对象。

  1. 接收一个 Promise 实例的数组或具有 Iterator 接口的对象;
  2. 如果元素不是 Promise 对象,则使用 Promise.resolve 转成 Promise 对象,也就意味着如果不是 Promise 对象,就让他变成完成状态的 Promise
  3. 如果全部成功,状态变为 resolved,返回值将组成一个数组传给回调;
  4. 只要有一个失败,状态就变为 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