JS数组降维的实现Array.prototype.concat.apply([], arr)


Posted in Javascript onApril 28, 2020

把多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,最近跟着黄轶老师学习Vue2.6.1.1版本源码时,看到源码对二维数组降维的代码,所以这里来写一篇,记录一下,加强印象

二维数组降为一维数组

循环降维

let children = [1, 2, 3, [4, 5, 6], 7, 8, [9, 10]];
function simpleNormalizeChildren(children) {
 let reduce = [];
 for (let i = 0; i < children.length; i++) {
  if (Array.isArray(children[i])) {
   for (let j = 0; j < children[i].length; j++) {
    reduce.push(children[i][j]);
   }
  } else {
   reduce.push(children[i]);
  }
 }
 return reduce;
}
simpleNormalizeChildren(children) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

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

concat降维

MDN上对于concat的介绍

“concat creates a new array consisting of the elements in the object on which it is called, followed in order by, for each argument, the elements of that argument (if the argument is an array) or the argument itself (if the argument is not an array).”

concat

如果concat方法的参数是一个元素,该元素会被直接插入到新数组中;如果参数是一个数组,该数组的各个元素将被插入到新数组中;将该特性应用到代码中:

let children = [1, 2, 3, [4, 5, 6], 7, 8, [9, 10]];
function simpleNormalizeChildren(children) {
 let reduce = [];
 for (let i = 0; i < children.length; i++) {
  reduce = reduce.concat(children[i]);
 }
 return reduce;
}
simpleNormalizeChildren(children) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

children 的元素如果是一个数组,作为concat方法的参数,数组中的每一个子元素会被独立插入进新数组。利用concat方法,我们将双重循环简化为了单重循环。

apply和concat降维

MDN上对于apply方法的介绍

“The apply() method calls a function with a given this value and arguments provided as an array.”

apply

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

let children = [1, 2, 3, [4, 5, 6], 7, 8, [9, 10]];
function simpleNormalizeChildren(children) {
 return Array.prototype.concat.apply([], children);
}
simpleNormalizeChildren(children) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

children作为apply方法的第二个参数,本身是一个数组,数组中的每一个元素(还是数组,即二维数组的第二维)会被作为参数依次传入到concat中,效果等同于[].concat(1, 2, 3, [4, 5, 6], 7, 8, [9, 10])。利用apply方法,我们将单重循环优化为了一行代码

Vue2.6.11版本源码降维

let children = [1, 2, 3, [4, 5, 6], 7, 8, [9, 10]];
// :any 可以去掉 这里是Vue通过Flow指定传入的参数类型可以是任意类型
function simpleNormalizeChildren(children: any) {
 for (let i = 0; i < children.length; i++) {
  if (Array.isArray(children[i])) {
   return Array.prototype.concat.apply([], children);
  }
 }
 return children;
}

simpleNormalizeChildren(children); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

多维数组降为一维数组

递归降维

递归函数就是在函数体内调用自己;

递归函数的使用要注意函数终止条件避免死循环;

// 多维数组
let children = [1, [2,3], [4, [5, 6, [7, 8]]], [9, 10]];
function simpleNormalizeChildren(children) {
 for (let i = 0; i < children.length; i++) {
  if (Array.isArray(children[i])) {
   children = Array.prototype.concat.apply([], children);
   for(let j =0; j<children.length; j++) {
    simpleNormalizeChildren(children)
   }
  }
 }
 return children;
}
simpleNormalizeChildren(children); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

到此这篇关于JS数组降维的实现Array.prototype.concat.apply([], arr)的文章就介绍到这了,更多相关JS数组降维内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(2)
Dec 23 Javascript
js验证是否为数字的总结
Apr 14 Javascript
javascript 获取网页标题代码实例
Jan 22 Javascript
查找Oracle高消耗语句的方法
Mar 22 Javascript
jQuery+easyui中的combobox实现下拉框特效
Feb 27 Javascript
jQuery插件zoom实现图片全屏放大弹出层特效
Apr 15 Javascript
jquery实现点击变换导航样式的方法
Aug 31 Javascript
JavaScript预解析及相关技巧分析
Apr 21 Javascript
浅谈html转义及防止javascript注入攻击的方法
Dec 04 Javascript
Javascript设计模式之装饰者模式详解篇
Jan 17 Javascript
详解JavaScript中精度失准问题及解决方法
Feb 04 Javascript
再也不怕 JavaScript 报错了,怎么看怎么处理都在这儿
Dec 09 Javascript
React中Ref 的使用方法详解
Apr 28 #Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 #Javascript
react PropTypes校验传递的值操作示例
Apr 28 #Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
Apr 28 #Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
Apr 27 #Javascript
浅析vue cli3 封装Svgicon组件正确姿势(推荐)
Apr 27 #Javascript
react组件基本用法示例小结
Apr 27 #Javascript
You might like
其他功能
2006/10/09 PHP
FCKeditor的安装(PHP)
2007/01/13 PHP
使用GROUP BY的时候如何统计记录条数 COUNT(*) DISTINCT
2011/04/23 PHP
swoole锁的机制代码实例讲解
2021/03/04 PHP
用正则xmlHttp实现的偷(转)
2007/01/22 Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
2011/05/28 Javascript
jQuery打印图片pdf、txt示例代码
2014/07/22 Javascript
AngularJs 弹出模态框(model)
2016/04/07 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
2016/08/11 Javascript
js初始化验证实例详解
2016/11/26 Javascript
基于jquery实现多级菜单效果
2017/07/25 jQuery
原生JS实现简单的无缝自动轮播效果
2018/09/26 Javascript
使用Javascript简单计算器
2018/11/17 Javascript
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
2019/10/15 Javascript
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python采集博客中上传的QQ截图文件
2014/07/18 Python
Python实现的tab文件操作类分享
2014/11/20 Python
django+mysql的使用示例
2018/11/23 Python
flask-restful使用总结
2018/12/04 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
2020/03/01 Python
150行Python代码实现带界面的数独游戏
2020/04/04 Python
全网最全python库selenium自动化使用详细教程
2021/01/12 Python
CSS3教程(4):网页边框和网页文字阴影
2009/04/02 HTML / CSS
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
市场营销专业毕业生自荐信
2013/11/02 职场文书
大学自我鉴定范文
2013/12/26 职场文书
女娲补天教学反思
2014/02/05 职场文书
学生会竞选演讲稿纪检部
2014/08/25 职场文书
市级绿色学校申报材料
2014/08/25 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
西岭雪山导游词
2015/02/06 职场文书
淮阳太昊陵导游词
2015/02/10 职场文书
2015年信访工作总结
2015/04/07 职场文书
启动Tomcat时出现大量乱码的解决方法
2021/06/21 Java/Android
聊聊redis-dump工具安装问题
2022/01/18 Redis