JS面试鄙视题 - flat

310 阅读1分钟

简介

谈起前端面试的js部分, 大部分的面试官都喜欢出这样的题目, 比如手写一个原生的js方法. 这种题目很能考察到候选人的js基本功.

今天我们继续来手写一个常见的js方法. flat.

flat的用法

flat是数组的一个方法, 接受一个参数, depth, 默认为1, 即只扁平化一层.

  • flat(): 扁平化一层
  • flat(0):不做扁平化, 原数据返回
  • flat(Infinity): 扁平化所有数组对象.

实例

const arr = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];

// output: [1, 2, 3, 4, Array(3)]
arr.flat();

// output: [1, 2, Array(3)]
arr.flat(0);

// output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.flat(Infinity);

知道了flat的用法后, 我们来试着手写试试.

先来实现个简单的, 只扁平化一层.

  1. 方案1: 使用concat
const flat = arr => [].concat(...arr);
  1. 方案2: 使用reduce
const flat = arr => arr.reduce((result, item) => result.concat(item), []);
  1. 方案3: for, forEach, while 等
const flat = arr => {
  let newArr = [];

  arr.forEach(item => {
    newArr = newArr.concat(item);
  });

  return newArr;
};

看起来是不是挺简单. 有了这个基础, 我们来实现一个和原生的flat功能一致的方法. 支持扁平化任意的层级.

手写flat, 支持任意层级.

实现的思路是: reduce + concat + isArray + recursivity

  1. 方案1:
const flat = (arr, depth = 1) => {
  if(depth > 0){
    return arr.reduce((result, item) => {
      const newItem = Array.isArray(item) ? flatAny(item, depth - 1): item;
      return result.concat(newItem);
    }, []);
  }

  return arr;
};
  1. 方案2:
const flat = (arr, depth = 1) => {
  if(depth > 0){
    let newArr = [];

    arr.forEach(item => {
      const newItem = Array.isArray(item) ? [].concat(flatAny2(item, depth -1)) : item;
      newArr = newArr.concat(newItem);
    });

    return newArr;
  }

  return arr;
};

这里我只实现了两种, 还可以有更多的方案.

code