• 数组扁平化的方法


    什么是“数组扁平化


    用简单的话来说,就是将一个多维数组变为一个一维数组。例如,将数组[1, 2, [3, [4, 5]], [6, 7]]扁平化处理后输出[1, 2, 3, 4, 5, 6, 7]。

    实现“数组扁平化”方法

    方式1:使用基础的递归遍历

    声明一个函数,遍历数组的每个元素,判断当前元素是否仍是数组,是的话递归执行这个函数,并把执行结果与当前结果数组合并,不是数组则直接将当前元素push到结果数组中。

    function flatten(arr) {
      let result = [];
      // 此处也可使用for...of遍历
      for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
          result = result.concat(flatten(arr[i]));
        } else {
          result.push(arr[i]);
        }
      }
      return result;
    }
     

    方式2:使用reduce函数递归遍历 

    与第一种方法思路是一样的,区别在于这里利用reduce函数的特性遍历数组并保存每一次的计算结果。

    function flatten(arr) {
      return arr.reduce((pre, current) => {
        if (Array.isArray(current)) {
          return pre.concat(flatten(current));
        } else {
          return pre.concat(current);
        }
      }, []);
    },


    方式3:数组强制类型转换

    对于数组对象,toString方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。返回的字符串使用split分割成子字符串数组,最后将数组中每个元素的类型转换为Number型。

    function flatten(arr) {
      return arr.toString().split(',').map((item) => Number(item));
    },
     

     为了方便理解,在浏览器调试工具的Console下逐步执行各个步骤,每步的输出结果如下图所示。

     

    方式4:while循环结合findIndex与concat

    在while循环中,使用findIndex判断当前数组是否是一个多维数组(即判断数组是否存在Array类型的元素),如是,则使用…扩展操作符展开作为concat方法的参数进行合并(如下图)并赋值给当前数组,再执行下一次循环的条件判断,直至得到一个一维数组。

    function flatten(arr) {
      while (arr.findIndex((item) => Array.isArray(item)) > 0) {
        arr = [].concat(...arr);
      }
      return arr;
    }

     

    可能有些小伙伴不太能理解 arr = [].concat(...arr);这一行代码,其实这一行代码的作用就相当于把所给多维数组剥开一层(如下图所示),多次循环执行直至得到一个一维数组。 

    方式5:直接使用ES6的flat方法

    直接使用ES6提供的flat方法实现扁平化。falt()方法会按照指定的深度递归遍历数组,arr.flat([depth]),参数depth不填时默认值为1,depth为Infinity表示展开任意深度的嵌套数组。

    function flatten(arr) {
      return arr.flat(Infinity);
    }

    // Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组

    const arr = [1,[2,3],[4,[5,[6]],7]];
    arr.flat(Infinity);
    // [1,2,3,4,5,6,7];

    // 传入 <=0 的整数将返回原数组,不“拉平”
    arr.flat(0);
    // [1,[2,3],[4,[5,[6]],7]]
    arr.flat(-6);
    // [1,[2,3],[4,[5,[6]],7]]

    // 如果原数组有空位,flat()方法会跳过空位
    [1,2,3,4,5,6,,].flat();
    // [1,2,3,4,5,6]


    方式6:使用JSON的函数和正则表达式

    使用JSON的序列化函数stringify()先对数组进行序列化,再用正则去掉[],得到的结果在最外层加上[]后使用JSON.parse()恢复成数组对象。

    function flatten(arr) {
      let result = JSON.stringify(arr).replace(/(|

    |
    )/g,'');
      result = '[' + result + ']';
      return JSON.parse(result);
    }
     


    方式7:使用堆栈stack

    创建一个栈结构和一个存放结果的空数组,然后遍历栈结构,判断元素如果是数组就使用扩展操作符展开再次入栈,不是就添加到结果数组的开头。

    // 无递归数组扁平化
    function flatten(arr) {
      const stack = [...arr];
      const res = [];
      while (stack.length) {
        // 出栈 从 stack 中取出一个元素
        const next = stack.pop();
        if (Array.isArray(next)) {
          // 展开一层重新入栈
          stack.push(...next);
        } else {
          res.unshift(next);
        }
      }
      return res;
    }



    方式8:使用Generator 函数与递归结合

    Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。思路还是遍历当前数组,判断数组元素是否是数组,是则使用 yield 语句递归执行这个 Generator 函数,不是则使用 yield 表达式返回当前值。

    function* flatten(arr){
      for(const item of arr) {
        if(Array.isArray(item)) {
          yield* flatten(item);
        } else {
          yield item;
        }
      }
    }
    const array = [1, 2, [3, [4, 5]], [6, 7]];
    const flattened = [...flatten(array)];

  • 相关阅读:
    【进阶C语言】动态内存分配
    APAUNet
    乐歌入选毕马威“第二届新国货50榜单”,用实力演绎国潮当自强
    Java—类加载的基本机制和过程
    Pytorch实现波阻抗反演
    网站优化的技能有哪些内容?
    javaweb教师招聘管理系统ssm
    GB/T-2423.xx 环境试验文件,整理包括了最新的文件里面
    vue3中使用插件vite-plugin-svg-icons
    深入理解多线程(第二篇)
  • 原文地址:https://blog.csdn.net/qq_43532275/article/details/133141069