数组的元素可能是数组,这样一层层嵌套,可能得到一个嵌套很深的数组,数组降维要做的事就是把嵌套很深的数组展开,一般最后得到一个一维数组,其中的元素都是非数组元素,比如数组[1, [2, 3, [4, 5], 6], 7, 8]降维展开后是[1, 2, 3, 4, 5, 6, 7, 8].

1.普通方法

  1. function flattenMd(arr){
  2. var result=[]
  3. function flatten(arr){
  4. for (var i = 0; i < arr.length; i++) {
  5. if (Array.isArray(arr[i])) {
  6. flatten(arr[i]);
  7. }else{
  8. result.push(arr[i]);
  9. }
  10. }
  11. }
  12. flatten(arr);
  13. return result;
  14. }
  15. var arr=[1, [2, 3, [4, 5], 6], 7, 8]
  16. console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]

备注:这里我使用了Array.isArray()方法来检测对象时候是数组,没有考虑ES5以下的兼容性,关于js对象类型的检测可以参考我的另一篇博文Javascript数据类型检测,当然了如果支持ES5的话,还可以直接使用数组的迭代方法forEach(或map、reduce等),Es6中还有for···in可以使用,这里就不赘述了。

这个方法需要定义两个函数,其中flatten方法位于内部。还可以改造成闭包的形式

  1. function flattenMd(ret) {
  2. function flatten(arr) {
  3. arr.forEach(function(item) {
  4. (Array.isArray(item)) ? flatten(item) : ret.push(item);
  5. });
  6. }
  7. return function(arr) {
  8. flatten(arr);
  9. return ret;
  10. }
  11. }([]);
  12. var arr=[1, [2, 3, [4, 5], 6], 7, 8]
  13. console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]

2.数组concat方法

熟悉数组操作方法的开发人员应该知道数组concat方法的特性:传递给concat方法的参数序列中如果包含数组,则会将这个数组的每一项添加到结果数组中,这就使数组的这个方法具有了天然的展开二维数组的能力,比如:

  1. var colors=['red','green','blue'];
  2. var colors2=colors.concat('yellow',['black','brown']);
  3. console.log(colors2)//[ 'red', 'green', 'blue', 'yellow', 'black', 'brown' ]

需要注意的是如果数组的元素还是数组则不会再展开了,也就是concat方法只能降低一维。借助concat方法,可以得到另一种二维数组降维方法。

  1. function flatten2d(arr) {
  2. var result = [];
  3. for(var i = 0; i < arr.length; i++) {
  4. result = result.concat(arr[i]);
  5. }
  6. return result;
  7. }

上面的方法还可以进一步简化。我们知道apply方法是可以直接接受数组参数,这样我们连循环迭代都省了。

  1. function flatten2d(arr) {
  2. return Array.prototype.concat.apply([], arr);
  3. }

网上很多博客说使用递归很容易将二维的降维改造成多维的降维,实际上操作起来是比较复杂的,因为没有现成的方法能够判断某个数组是不是二维数组,也就不能判断递归的结束条件了。所以对于多维数组的降维需要重新规划使用concat方法可以避免方法一中多出的内部函数

对于多维数组

  1. function flattenMd(arr) {
  2. var result = [];
  3. for(var i = 0; i < arr.length; i++){
  4. if(arr[i] instanceof Array) {
  5. result = result.concat(flattenMd(arr[i]));
  6. }
  7. else {
  8. result.push(arr[i]);
  9. }
  10. }
  11. return result;
  12. }
  13. var arr=[1, [2, 3, [4, 5], 6], 7, 8]
  14. console.log(flattenMd(arr));[ 1, 2, 3, 4, 5, 6, 7, 8 ]

3.数组join和split方法的结合(有缺陷)

很多开发人员都知道数组的join方法可以将数组展开成字符串,但是不确定的是join方法能够展平数组,即使是多维数组,我们再使用split方法重新组合数组就行了。但是这个方法有天然缺陷,下面的例子中会看到

  1. function flattenMd(arr) {
  2. return arr.join().split(',');
  3. }
  4. var arr=['1', [null, 3, [4, 5], {K:1}], undefined, 8]
  5. console.log(flattenMd(arr));//[ '1', '', '3', '4', '5', '[object Object]', '', '8' ]

从结果可以看出,这样处理过后有几个缺点:一是所有类型的元素都会变成字符串;二是null、undefined会变成空字符串、对象会变成'[object Object]'。相当于调用了toString方法,当也不是说这个方法一无是处。对于同一种类型的元素,还是很有用处的,比如要求多维数组的最大值。

  1. function flattenMd(arr) {
  2. return arr.join().split(',');
  3. }
  4. var arr=[1, [5, 3, [8, 5], 5,[15]], 9, 13]
  5. console.log(Math.max.apply(null,flattenMd(arr)));//15

参考

优雅的数组降维——Javascript中apply方法的妙用

Javascript实现的数组降维——维度不同,怎么谈恋爱的更多相关文章

  1. Javascript实现的数组降维——维度不同,怎么谈恋爱(修订版)

    数组的元素可能是数组,这样一层层嵌套,可能得到一个嵌套很深的数组,数组降维要做的事就是把嵌套很深的数组展开,一般最后得到一个一维数组,其中的元素都是非数组元素,比如数组[1, [2, 3, [4, 5 ...

  2. 优雅的数组降维——Javascript中apply方法的妙用

    将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换.本文将从朴素的循环转换开始,逐一介绍三 ...

  3. 数组降维-JavaScript中apply方法妙用

    海纳百川,有容乃大 1.普通循环转换方式 将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转 ...

  4. JavaScript学习笔记——数组

    javascript数组数组是一个可以存储 一组 或是 一系列 相关数据 的 容器. 一.为什么要使用数组. (1)为了解决大量相关数据的存储和使用的问题. (2)模拟真是的世界. 二.如何创建数组 ...

  5. php中使用array_reduce给数组降维

    PHP里面最强大的工具,就是数组,它融合了多种数据结构的特点,数组.队列.栈.哈希表等等,而且容器可以兼容各种类型,任意嵌套,简直无所不能.围绕着数组,PHP原生支持了一些列的函数,使得数组在实际编程 ...

  6. 面试官:JavaScript如何实现数组拍平(扁平化)方法?

    面试官:JavaScript如何实现数组拍平(扁平化)方法? 1 什么叫数组拍平? 概念很简单,意思是将一个"多维"数组降维,比如: // 原数组是一个"三维" ...

  7. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  8. JavaScript 基础回顾——数组

    JavaScript是无类型语言,数组元素可以具有任意的数据类型,同一个数组的不同元素可以具有不同类型.数组的元素设置可以包含其他数组,便于模拟创建多维数组. 1.创建数组 在JavaScript中, ...

  9. javascript里面的数组,json对象,动态添加,修改,删除示例

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

随机推荐

  1. Swift_提醒框

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Menlo; color: #ffffff } p.p2 { margin: 0.0px 0. ...

  2. linux 系统、命令、软件

    软件名称:Putty 使用方法:http://jingyan.baidu.com/article/e73e26c0eb063324adb6a737.html 需要资料: 服务IP:228.5624.5 ...

  3. hibernate中java类的成员变量类型如何映射到SQL中的数据类型变化

    hibernate映射文件??.hbm.xml配置映射元素详解--Hibernate映射类型 在从Hibernate的java的成员类型映射到SQL中的数据类型,其内映射方式它满足,SQL可以自己调制 ...

  4. Apache Curator: Zookeeper客户端

    Apache Curator Framework url: http://curator.apache.org/curator-framework/ The Curator Framework is ...

  5. c++文件输入输出流fstream,对输入>>和输出<<重载

    1. fstream 继承自iostream --> 要包含头文件#include<fstream> 2. 建立文件流对象 3. 打开文件夹 4. 测试是否打开成功 5. 进行读写操 ...

  6. SQLServer日期函数用法

    --1.显示本月第一天 ,) ),)) --2.显示本月最后一天 ,),,))) ,,,)) --3.上个月的最后一天 ,,)) --4.本月的第一个星期一 , ) --5.本年的第一天 ,) --6 ...

  7. 虚拟机NAT网络配置

    今天虚拟机NAT模式配置网络遇到一个奇葩问题.主机能ping同虚拟机时,虚拟机不能ping同主机.相反虚拟机ping通主机时,主机ping不通虚拟机. 最后花了一个小时,终于可以互通了,做一个记录: ...

  8. http://www.microsoft.com/en-pk/download/details.aspx?id=40762

    http://www.microsoft.com/en-pk/download/details.aspx?id=40762

  9. 奇怪的bug(ant-design)

    ant-motion模板代码启动报错. 多了一层 import 会导致 less 编译的顺序发生变化,很奇怪的问题,还需要再深入看看.目前 ant-d.less 可以先改成这样来解决: + @impo ...

  10. 卸载linux Mint自带jdk并安装最新jdk

    查看安装的软件包sudo dpkg --list | grep -i jdk 删除jdksudo apt-get purge openjdk* 删除其他的包sudo apt-get purge ice ...