粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • Javascript

    • 简介
    • 获取某年某月的天数
    • 日期格式化
    • 展开多级数组
    • 判断数据类型的方案
    • 文件上传与下载
    • 柯里化
    • 闭包
    • delete
    • 垃圾回收
    • 节流与防抖
    • apply,call,bind
    • blob与file
    • Event Loop
    • Promise
    • 定时器
    • 原型与原型链
    • 作用域
    • 执行上下文栈
    • 变量对象
    • 作用域链
    • ECMAScript规范解读this
    • 执行上下文
    • 参数按值传递
    • 类数组与arguments
    • 浮点数
    • Symbol的用法
    • 箭头函数
    • 类型转换
    • 获取dom元素的方式
    • 浅拷贝与深拷贝
    • ES6+的新语法糖和方法整理
    • 学习过程中学到的一些取巧之法

数组扁平化的多种方案

vuePress-theme-reco 粥里有勺糖    2018 - 2023

数组扁平化的多种方案

粥里有勺糖 2020-04-14 大前端javascript

# 数组扁平化的多种方案

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

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

# 题目描述

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

# 1.Array.flat

这个方法是ES2019 (opens new window)提供的API,可以直接将数组进行扁平化处理

Array.prototype.flat(arr,deep)

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

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

运行示例

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]]
1
2
3

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

# 2. 递归

# 2.1 常规递归

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

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

具体实现如下

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]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2.2 reduce 递归

调用数组的reduce方法,结合concat方法进行:

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

具体实现如下:

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 ]
1
2
3
4
5
6
7
8
9

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

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

步骤:

  1. 执行JSON.stringify
  2. 执行replace替换掉[或]
  3. 再调用JSON.parse生成
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 ]
1
2
3
4
5
6
7
8

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

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

具体实现如下

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 ]
1
2
3
4
5
6
7
8
9
Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34