JavaScript实现flatten多种方法

3,644 阅读2分钟

简介

我们在网上看到很多的关于数组的面试题,比如说给如下一个数组,把它拍平、去重、升序

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

其实这个题有很多种解法,比如用 Array.prototype.flat,或者自己实现一个 flatten 函数,我们这里主要关注的时 flat 方法的实现。

第一种解法

用最新的语法

let arr = [8, [5, 9, 4], 1, 3, [7, 5, 10, [3, 4, 6, 2]], 4, 3, 2, 4];
let newArr = Array.from(new Set(arr.flat(Infinity))).sort((a, b) => {
  return a - b;
});
console.log(newArr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1、就是先拍平一个多维数组 arr.flat(ES6 语法) 2、再通过 Set 集合做去重 3、再通过 Array.fromSet 集合转为数组 4、再通过 sort 排序

如果不了解 flat 的函数的话,可以参考mdn Array.prototype.flat(),或者看阮一峰老师的 flat 介绍。 Set 集合的讲解可以参考mdn Set,或者看阮一峰老师的 Set 介绍。 我们这里主要讨论 flat 的实现。

第二种解法

let arr = [8, [5, 9, 4], 1, 3, [7, 5, 10, [3, 4, 6, 2]], 4, 3, 2, 4];
let newArr = Array.from(new Set(arr.toString().split(",")))
  .map(item => {
    return parseInt(item);
  })
  .sort((a, b) => {
    return a - b;
  });
console.log(newArr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1、我们调用 Array 上的 toString 方法把他转换为一个字符串

arr.toString();
// "8,5,9,4,1,3,7,5,10,3,4,6,2,4,3,2,4"

这列我们就不讨论为什么返回的结果里面不包含‘[]’这两个字符串,后面我在写一篇博客来说数组,的 valueOf、toString 方法。 2、再把字符串通过 Array.prototype.split 方法转换为数组 3、再通过 Set 集合做去重 4、再通过 Array.fromSet 集合转为数组 5、再通过 sort 排序

第三种解法

自己通过封装一个 flatten,在不基于 Array.prototype.flat 方法上实现一个拍平函数

ES6 实现

let arr = [8, [5, 9, 4], 1, 3, [7, 5, 10, [3, 4, 6, 2]], 4, 3, 2, 4];
const flatten = arr =>
  Array.isArray(arr) ? arr.reduce((a, b) => [...a, ...flatten(b)], []) : [arr];
let newArr = Array.from(new Set(flatten(arr))).sort((a, b) => {
  return a - b;
});

// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ES5

let arr = [8, [5, 9, 4], 1, 3, [7, 5, 10, [3, 4, 6, 2]], 4, 3, 2, 4];
function flatten(arr) {
  return Array.isArray(arr)
    ? arr.reduce(function(prev, current) {
        return [...prev, ...flatten(current)];
      }, [])
    : [arr];
}
let newArr = Array.from(new Set(flatten(arr))).sort((a, b) => {
  return a - b;
});
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

实现思路

1、检测是否为数组 2、如果是数组,调用 reduce 函数实现合并函数 3、如果有嵌套数组,就递归调用该方法

总结

实现拍平数组大致有三种方法

  1. Array.prototype.flat 方法
  2. Array.prototype.toString 方法转为字符串,再 split
  3. 自己实现一个 flatten 函数