ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浅谈js数组扁平化的几种实现方式及其优缺点 手写ES10 flat

2022-03-26 02:01:34  阅读:187  来源: 互联网

标签:flat arr return 浅谈 res Array ES10 cur


前言

无论是做项目还是找工作,数组扁平化都是一种重要的知识技巧
在2019年发布的ES10中,js更是对数组新增了扁平化的API:Array.protoytype.flat
下面将给出flat实现的几种方式,顺便谈谈这些方式的优缺点

一、转成字符串处理

思路是将数组转成成字符串处理,通过join或者正则替换的方式过滤掉中括号
join是个神奇的api, 它将数组转换成字符串时会剔除掉串中所有的中括号, 相当于join方法内置了扁平化功能。 amazing~

function flatten1(arr) {
    if (!Array.isArray(arr)) return [] 
    // [0,[1,2,[3,4]]].join()  '0,1,2,3,4'
    return Array.prototype.join.call(arr).split(',')
}
function flatten2(arr1) {
    return JSON.stringify(arr1).replace(/\[|\]/g, '').split(',')
}

此招胜在简单粗暴,用起来大呼过瘾,但同时也败在简单粗暴 ———— 并非所有类型在整容成字符串之后还能完美的还原
拿序列化举例,JSON是一种常用的数据传输格式,对常用的数据载体如对象、数组的支持较好,而对于其他引用类型如Map、Set、Date等的支持欠佳,因此在使用序列化实现flat或者深复制的时候,需要根据实际场景来判断使用

适合数组元素全是字符串或者数字的场景下使用

二、递归实现flat

转成字符串确然用起来爽,但是也存在支持的类型有限的问题

function flatten3(arr) {
    let res = []
    arr.forEach(v => Array.isArray(v) ? res = res.concat(flatten3(v)) : res.push(v))
    return res
}

以上实现,思路还算清晰,但似乎还可以尝试一下更加简洁的实现方式

function flatten4(arr) {
    return Array.prototype.reduce.call(arr, (total, cur) => total.concat(Array.isArray(cur) ? flatten4(cur) : cur), [])
}

递归方式实现可以避免字符串方式类型不支持的问题,但每当函数调用时都会在栈里储存一些信息,如参数、局部变量等等,递归时函数执行次数过多会抛出栈溢出异常,因此探讨一下其他的实现方式也是很有必要的

三、非递归实现flat

这里尝试用while循环+队列实现一下非递归的flat

function flatten5(arr) {
    let res = []
    while (true) {
        if (arr.length === 0) break
        let cur = arr.shift()
        Array.isArray(cur) ? arr.unshift(...cur) : res.push(cur)
    }
    return res
}

四、ES10 flat 实现指定深度的数组扁平化

ES10中,官方提供的原生flat方法支持传入一个depth参数,这里尝试实现一下

function flatten6(arr,depth = 1) {
    if (!Array.isArray(arr)) return []
    if(typeof depth !== 'number') depth = 1
    let curDepth = 1  
    function flat(arr,curDepth){
        return Array.prototype.reduce.call(arr, (total, cur) =>{
            // 无需扁平化的场景: 超过深度阈值 或 当前元素非数组
            if(curDepth > depth || !Array.isArray(cur)){
                total.push(cur)
                return total
            }else{
                curDepth ++
                return total.concat(flat(cur,curDepth))
            }
        }
        , [])
    }
    return flat(arr,curDepth)
}

测试

标签:flat,arr,return,浅谈,res,Array,ES10,cur
来源: https://www.cnblogs.com/ltfxy/p/16057491.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有