JavaScript实现数组降维详解

 更新时间:2017年01月05日 10:03:20   作者:Mervyn Zhang  
大家都知道将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性和数据结构的思想实现更为简洁优雅的转换。下面跟着小编一起来学习学习关于JavaScript如何实现数组降维吧。

二维数组降维

二维数组只有两个维度,降维比较简单,也不用考虑太复杂的算法逻辑,我们看一下二维数组降维的几种方法;

遍历降维

var arr = [
  ['h', 'e', 'l', 'l', 'o'],
  ['m', 'y'],
  ['w', 'o', 'r', 'l', 'd'],
  ['!']
];
var result = [];
for (var r = 0; r < arr.length; r++) {
  for (var c = 0; c < arr[r].length; c++) {
    result.push(arr[r][c]);
  }
}
console.log(result); //=>[ 'h', 'e', 'l', 'l', 'o', 'm', 'y', 'w', 'o', 'r', 'l', 'd', '!' ]

此方法思路简单,利用双重循环遍历二维数组中的每个元素并放到新数组中。

使用concat

利用concat方法,可以将双重循环简化为单重循环:

var arr = [
  ['h', 'e', 'l', 'l', 'o'],
  ['m', 'y'],
  ['w', 'o', 'r', 'l', 'd'],
  ['!']
];
var result = [];
for (var r = 0, result = []; r < arr.length; r++) {
  result = result.concat(arr[r]);
}
console.log(result); //=>[ 'h', 'e', 'l', 'l', 'o', 'm', 'y', 'w', 'o', 'r', 'l', 'd', '!' ]

arr的每一个元素都是一个数组或参数,作为concat方法的参数,数组中的参数或每一个子元素又都会被独立插入进新数组。

使用apply+concat

apply方法会调用一个函数,apply方法的第一个参数会作为被调用函数的this值,apply方法的第二个参数(一个数组,或类数组的对象)会作为被调用对象的arguments值,也就是说该数组的各个元素将会依次成为被调用函数的各个参数;

var arr = [
  ['h', 'e', 'l', 'l', 'o'],
  ['m', 'y'],
  ['w', 'o', 'r', 'l', 'd'],
  ['!']
];
var result = Array.prototype.concat.apply([], arr);
console.log(result); //=>[ 'h', 'e', 'l', 'l', 'o', 'm', 'y', 'w', 'o', 'r', 'l', 'd', '!' ]

利用apply方法,只需要一行代码就可以完成二维数组降维了。

多维数组降维

多维数组就没二维数组那么简单了,因为不确定数组的深度,所以也不能进行遍历来降维,只能通过递归或者栈方法来实现。

递归

Array.prototype.deepFlatten = function() {
  var result = []; //定义保存结果的数组
  this.forEach(function(val, idx) { //遍历数组
    if (Array.isArray(val)) { //判断是否为子数组
      val.forEach(arguments.callee); //为子数组则递归执行
    } else {
      result.push(val); //不为子数组则将值存入结果数组中
    }
  });
  return result; //返回result数组
}
var arr = [2, 3, [2, 2],
  [3, 'f', ['w', 3]], { "name": 'Tom' }
];
console.log(arr.deepFlatten()); //=>[ 2, 3, 2, 2, 3, 'f', 'w', 3, { name: 'Tom' } ]

这是通过递归的方法实现了多维数组的降维,在这里面,我有使用了原型链将方法封装进了Array原型中,可以直接在数组方法中调用。

栈方法

Array.prototype.deepFlatten = function() {
  var result = []; //定义保存结果的数组
  var stack = this; //将数组放入栈中
  while (stack.length !== 0) { //如果栈不为空,则循环遍历
    var val = stack.pop(); //取出最后一个值
    if (Array.isArray(val)) { //判断是不是数组
      stack = stack.concat(val); //如果是数组就将拼接入栈中
    } else {
      result.unshift(val); //如果不是数组就将其取出来放入结果数组中
    }
  }
  return result;
}
var arr = [2, 3, [2, 2],
  [3, 'f', ['w', 3]], { "name": 'Tom' }
];
console.log(arr.deepFlatten()); //=>[ 2, 3, 2, 2, 3, 'f', 'w', 3, { name: 'Tom' } ]

这是通过栈方法,建立了一个栈,将数组的内容存进去,然后逐个取出来,如果取出来的是个数组,就将这个数组打散拼接进栈中,在出栈一个,这样循环。

多维数组降维的方法也可以降维二维数组,但是有点大材小用,还是用对的方法做对的事才是最好的!

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

相关文章

  • JavaScript获取上传进度的几种方式实现

    JavaScript获取上传进度的几种方式实现

    进度条的应用是为了显示的告诉用户文件上传了多少,本文主要介绍了JavaScript获取上传进度的几种方式,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-08-08
  • JavaScript实现读取与输出XML文件数据的方法示例

    JavaScript实现读取与输出XML文件数据的方法示例

    这篇文章主要介绍了JavaScript实现读取与输出XML文件数据的方法,结合实例形式分析了JavaScript基于ActiveXObject实现载入、读取与输出xml文件数据的相关操作技巧,需要的朋友可以参考下
    2018-06-06
  • JavaScript cookie与session的使用及区别深入探究

    JavaScript cookie与session的使用及区别深入探究

    这篇文章主要介绍了Java中Cookie和Session详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下
    2022-10-10
  • 微信小程序开发之录音机 音频播放 动画实例 (真机可用)

    微信小程序开发之录音机 音频播放 动画实例 (真机可用)

    这篇文章主要介绍了微信小程序开发之录音机 音频播放 动画实例 (真机可用),这里整理了详细的代码,有需要的小伙伴可以参考下。
    2016-12-12
  • 初步使用bootstrap快速创建页面

    初步使用bootstrap快速创建页面

    初步尝试使用Express搭建了一个Web框架,那么接下来就是要在该框架下写上自己的页面,快速创建页面这里选择了bootstrap前端框架,通过它即使你不太懂前端设计,写出来的页面也不会太难看,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • js实现从左向右滑动式轮播图效果

    js实现从左向右滑动式轮播图效果

    这篇文章主要为大家详细介绍了js实现从左向右滑动式轮播图效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • JavaScript 正则应用详解【模式、欲查、反向引用等】

    JavaScript 正则应用详解【模式、欲查、反向引用等】

    这篇文章主要介绍了JavaScript 正则应用,结合实例形式详细分析了JavaScript 正则表达式模式、欲查、反向引用等相关概念、原理与操作注意事项,需要的朋友可以参考下
    2020-05-05
  • JavaScript错误处理之分析 Uncaught(in promise) error的原因及解决方案

    JavaScript错误处理之分析 Uncaught(in promise) error的

    在开发过程中,JavaScript的错误处理是一个老生常谈的话题,当应用程序发生未捕获的异常时,Uncaught(in promise) error是其中最常见的错误类型,这篇文章将从多个方面详细阐述这种错误类型的原因与解决方案,感兴趣的朋友一起看看吧
    2023-12-12
  • JS实现的找零张数最小问题示例

    JS实现的找零张数最小问题示例

    这篇文章主要介绍了JS实现的找零张数最小问题,涉及javascript数学运算相关操作技巧,需要的朋友可以参考下
    2017-11-11
  • 详解JavaScript引擎V8执行流程

    详解JavaScript引擎V8执行流程

    本文主要讲解的是V8的技术,是V8的入门篇,主要目的是了解V8的内部机制,希望对前端,快应用,浏览器,以及nodejs同学有些帮助。这里不涉及到如何编写优秀的前端,只是对JS内部引擎技术的讲解
    2021-06-06

最新评论