• 滴滴实习面试题


    滴滴实习面试题

    本文写于 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);
          })
        }
      })
    }
    

    (完)

  • 相关阅读:
    Mybatis连接配置文件详解
    MyBatis映射配置文件详解
    AGC 016 C
    CodeForces
    UVA
    某5道CF水题
    DZY Loves Chinese / DZY Loves Chinese II
    [SHOI2016] 黑暗前的幻想乡
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/xhyccc/p/13495020.html
Copyright © 2020-2023  润新知