---
url: https://sugarat.top/bigWeb/js/p3.md
---

# 数组扁平化的多种方案

工作中针对部分嵌套了多层数组的数据，采用数组扁平化能提升代码的可阅读性

同时面试过程中，通常也会被作为一道手写代码题。考察候选人对现有API的熟练度/语法糖和应变能力，通常会叫列出你能实现的所有方案

## 题目描述

简述：将多维数组转换为一维数组

## 1.Array.flat

这个方法是[ES2019](https://tc39.es/proposal-flatMap/)提供的API，可以直接将数组进行扁平化处理

`Array.prototype.flat(arr,deep)`

* 参数1:`arr` 待操作的数组
* 参数2:`deep` 展开深度
  * 默认:1
* 返回:一个新的数组

深度可以指定为 `Infinity`，表示展开所有的层级

**运行示例**

```js
console.log([1, [2], [3, [[4]]]].flat(Infinity)); // [1,2,3,4]
console.log([1, [2], [[3]].flat()); // [1,2,[3]]
console.log([1, [2], [[3]].flat(1)); // [1,2,[3]]
```

当然这个方法并不一定是面试官想要看到的方法。

## 2. 递归

### 2.1 常规递归

这个是比较常规的解法，实现方案很多，这里介绍一个简单的：

1. 使用`for...of`遍历数组
2. 判断每一项的类型，如果是数组则进行递归调用，否则直接加入数组

具体实现如下

```js
function myFlat(arr) {
    let res = []
    // 遍历
    for (const a of arr) {
        // 判断是否是数组
        if(a instanceof Array){
            // 是,则递归调用
            res = res.concat(myFlat(a))
        }else{
            // 不是则直接放入
            res.push(a)
        }
    }
    return res;
}

console.log(myFlat([1, [2], [3, [[4]]]]));// [1,2,3,4]
```

### 2.2 reduce 递归

调用数组的reduce方法，结合concat方法进行：

1. 对每一项进行判断，如果是数组则递归调用
2. 否则使用concat进行合并，返回新数组

具体实现如下:

```js
let a = [{ a: 1 }, { b: 2 }, 3, 4, 5, [6, [7, 8, [9]]]]

function myFlat(arr) {
    return arr.reduce((pre, cur) => {
        return pre.concat(Array.isArray(cur) ? myFlat(cur) : cur)
    }, [])
}
console.log(myFlat(a))
// [ { a: 1 }, { b: 2 }, 3, 4, 5, 6, 7, 8, 9 ]
```

## 3. replace + JSON.parse + JSON.stringify

这个是代码上比较简介的一个实现，但存在缺陷，如果字符串中的内容本身就包含`[`或`]`就会直接被处理掉

步骤：

1. 执行`JSON.stringify`
2. 执行`replace`替换掉`[`或`]`
3. 再调用`JSON.parse`生成

```js
function myFlat(arr) {
    arr = JSON.stringify(arr)
    arr = JSON.parse('[' + arr.replace(/\[|\]/g, '') + ']')
    return arr
}
let a = [{ a: 1 }, { b: 2 }, 3, 4, 5, [6, [7, 8, [9]]]]
console.log(myFlat(a))
// [ { a: 1 }, { b: 2 }, 3, 4, 5, 6, 7, 8, 9 ]
```

## 4. 扩展运算符+Array.some迭代

* `Array.prototype.some`方法判断是否有一项符合条件
* 如果有一项是数组则调用扩展运算符进行展开

具体实现如下

```js
let a = [{ a: 1 }, { b: 2 }, 3, 4, 5, [6, [7, 8, [9]]]]
function myFlat(arr) {
    while (arr.some(Array.isArray)) {
        arr = [].concat(...arr)
    }
    return arr
}
console.log(myFlat(a))
// [ { a: 1 }, { b: 2 }, 3, 4, 5, 6, 7, 8, 9 ]
```
