• 数据处理之 数组扁平化 (数组降维)顺带总结一下数组的方法


    Hello,   大噶好, 小葵花妈妈课堂开课啦。。。。。。

    我们日常工作中拿到的数据不可能是只有一维的平面数组, 百分之99.99  是数组里嵌套数组再套数组的n维数组 .............................

    这种让人想问候它xx的多维数组我们怎么把它变成一维数组, 也就是只有一个中括号 的数组 呢 ? 

    接下来我们 一步一步来实现它 ,  Follow me  

    讲降维之前,  我们先来回顾一下 数组  有哪些   方法   ?   

    给同学们一秒钟时间思考。。。

    请同学们 举手回答  。。。。 

    OK    为了方便记忆,我们可以把数组的方法分成两类 :

        1  不改变原数组的方法

        2   改变原数组的方法

    先说会改变原数组的方法 :  

     sort()   数组的排序方法 , 可以传一个回调函数, 不传参数默认按照字符串的unicode码位点排序

        所以不传参 的话    10  是 小于 2 的  。。。。先比第一位 1 < 2  ,只有第一位相等才会比第二位,

        所以 10 < 2,回调函数接受两个参数, 可以在回调函数中定义排序的规则,  执行后返回改变后的原数组

     

    reverse()   数组逆序      执行后返回改变后的原数组

     

    pop()   弹出数组的最后一个元素   执行后返回弹出的变量

     

    shift()  弹出数组的第一个元素   执行后返回弹出的变量

     

    push()  在数组的末尾加(可加多个元素)   执行后返回改变后的原数组的length

     

    unshift()  在数组的头部加(可加多个元素)   执行后返回改变后的原数组的length

     

    splice(start, deleteCount,  new可选)  用于删除指定区域的元素, 并可以在删除的区域添加新的元素

                      new可以是多个新元素

                      执行后返回被删除的元素

     

    copyWithin(start, end可选, stop可选)  复制 index = end 的元素   并  替换 掉 index = start 的元素  ,

                stop 表示 在第几位 停止复制( IE 11 及更早版本不支持 copyWithin() 方法),

                执行后返回改变后的原数组

     

    fill(value, start可选, end可选)   把数组的start 位  到 end 位 的元素 都用 value  替换掉  ,

                  只传value,数组的所有元素都用value替换,

                  执行后返回改变后的原数组

     

    不改变原数组的方法:  

    concat()        数组合并, 可以传数组也可以传参数列表   , 返回一个合并后的新数组

          如果合并的数组里面有引用值, 新数组中的引用值的地址和原来一样,

          改变其中一个,另一个也会发生改变, 所以并不能用来深拷贝。

          (下一期我们会来讨论一下 深浅拷贝 )

    includes(value, start可选)    从start处往后查找  value 是否在数组中, 返回一个布尔值

    indexOf(value, start可选)    从start 开始 往后查找  value,   返回找到的第一个值的索引,

                 没找到返回-1

    lastIndexOf(value, start可选) 从索引为start的元素开始往前查找,返回找到的第一个值的索引,

                 没找到返回-1

    join(string可选)   把数组里的每一项用string里的符号拼接成一个字符串,

            不传参数用逗号拼接成一个字符串

    find(callback)   按照callback里的筛选条件返回第一个符合条件的元素

    findIndex(callback)  按照callback里的筛选条件返回第一个符合条件的元素的索引

    toString()   把数组转换成字符串 == >  join()  ;

    slice(start可选, end可选)   从数组索引为start处开始复制到索引为(end - 1)的元素   

                 返回一个由复制出来的元素组成的数组,

                 不传参数复制整个数组,

                注意:不传参复制的数组内部如果有引用值的话,复制后引用值

                指向同一个地址, 不能实现深拷贝

    数组还有很多遍历的方法我就不一一列出来了, 

    我们开始进入正题   。。。。。。

    和 扁平化  数组有关的方法    : 

      1  flat(deep可选)  deep降维深度  ; deep = 0 不降维

              deep 等于几 就降几维,

              不传deep   降一维

      2  flatMap(callback)   callback 里可以操作数组, 只能降一维

    上例子:

    1 var a = [1, 2, 3, 4, 5, [2,3,4,[6,10]]];    // 3维数组
    2 
    3 var b = a.flat(2);  //  参数为  维数  减一
    4 console.log(b);  // b = [1, 2, 3, 4, 5, 2, 3, 4, 6, 10]
    5 
    6 var c = a.flatMap( (value, index, array) => {  //只能用于2维数组的降维
    7     return value + 1;
    8 });
    9 console.log(c); // c = [2, 3, 4, 5, 6, "2,3,4,6,101"]

    需要注意的是: 

     1   flat 只能用于已知维度的数组降维

     2   flatMap  如果数组内有引用值 , 引用值会先调用toString()方法转换成字符串再进行计算

    对于未知维度的数组, 我们需要 借用   reduce()  方法  

    reduce(callback, init可选)   俗称累加器   callback里写累加规则,  init 为初始值 

    //  多维度降维使用递归
    deepFlat = (arr) => {
        return arr.reduce((a, b) => {
           return  Array.isArray(b) ? [...a, ...deepFlat(b)] : [...a, b]
        }, [])
    };

    分析     给一个初始值 [] ,  第一次 a = 初始值[]  , b是数组的第一位  , 判断b是否是数组,

    如果是数组,递归继续降维,降维的结果和a 合并

    如果不是数组, 直接和a合并,  

    合并的结果作为下一次初始值,

    第二次 a 为 上一次得到的初始值, b 为数组的第二位, 以此类推 。。。。。。。

    这样写有个小问题, 如果第一次传进去的不是数组的话会报错 !

    Uncaught TypeError: arr.reduce is not a function

    所以如果不想加额外的判断的话,还可以这样写

    const flattenDeep = (arr) => {
        return Array.isArray(arr) ? arr.reduce((a, b) => { 
            return [...a, ...flattenDeep(b)]
            }, []) : [arr]
        };

    再分析    先判断传进来的实参arr是否是数组, 如果不是的话直接返回【arr】,

         如果是的话  再   调用 reduce()方法  进行递归降维 ,

    更骚的写法

    const flattenDeep = (arr) => Array.isArray(arr) ? arr.reduce((a, b) => [...a, ...flattenDeep(b)], []) : [arr];

    把  大括号  和  return 都  去掉  , 一句话 搞定  !!!

     

  • 相关阅读:
    python数据类型汇总
    mac下hadoop环境的搭建以及碰到的坑点
    mac搭建hadoop3.1.1伪分布模式 全网最详细教程!
    Mac中安装node.js和npm
    Mac抓包工具Charles的安装激活及使用
    mysql命令行访问远程数据库
    Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)
    iTerm2 配色方案
    jar包无法引入解决办法
    41 | 怎么最快地复制一张表?
  • 原文地址:https://www.cnblogs.com/LHLVS/p/10603470.html
Copyright © 2020-2023  润新知