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中 关于prototype属性实现继承的原理图
Apr 16 Javascript
JS获取select的value和text值的简单实例
Feb 26 Javascript
js 右侧浮动层效果实现代码(跟随滚动)
Nov 22 Javascript
小心!AngularJS结合RequireJS做文件合并压缩的那些坑
Jan 09 Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 Javascript
jQuery实现下拉菜单(内容为时间)的实时更新及图表的随动更新的方法
Jul 07 Javascript
新入门node.js必须要知道的概念(必看篇)
Aug 10 Javascript
Vue中引入样式文件的方法
Aug 18 Javascript
使用Node搭建reactSSR服务端渲染架构
Aug 30 Javascript
vue 解决文本框被键盘遮住的问题
Nov 06 Javascript
Vue2.0 实现页面缓存和不缓存的方式
Nov 12 Javascript
Vue中computed和watch有哪些区别
Dec 19 Vue.js
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
PHP时间类完整实例(非常实用)
2015/12/25 PHP
PHP session会话操作技巧小结
2016/09/27 PHP
PHP + plupload.js实现多图上传并显示进度条加删除实例代码
2017/03/06 PHP
php的常量和变量实例详解
2017/06/27 PHP
php用xpath解析html的代码实例讲解
2019/02/14 PHP
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
IE下js调试工具Companion.JS
2010/10/15 Javascript
理解Javascript_09_Function与Object
2010/10/16 Javascript
js将long日期格式转换为标准日期格式实现思路
2013/04/07 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
AngularJS进行性能调优的7个建议
2015/12/28 Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
2016/09/26 Javascript
JQuery中Ajax的操作完整例子
2017/03/07 Javascript
javascript中json对象json数组json字符串互转及取值方法
2017/04/19 Javascript
Cpage.js给组件绑定事件的实现代码
2017/08/31 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
vue增加强缓存和版本号的实现方法
2019/05/01 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
2019/08/20 Javascript
通过扫小程序码实现网站登陆功能
2019/08/22 Javascript
vue 中的 render 函数作用详解
2020/02/28 Javascript
Vue看了就会的8个小技巧
2021/01/21 Vue.js
python实现汉诺塔递归算法经典案例
2021/03/01 Python
python 字符串和整数的转换方法
2018/06/25 Python
Django中使用Whoosh进行全文检索的方法
2019/03/31 Python
关于django 1.10 CSRF验证失败的解决方法
2019/08/31 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
jupyter 使用Pillow包显示图像时inline显示方式
2020/04/24 Python
Django自关联实现多级联动查询实例
2020/05/19 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
Canvas与Image互相转换示例代码
2013/08/09 HTML / CSS
Diesel美国网上商店:意大利牛仔时装品牌
2020/12/10 全球购物
大学生实习期自我评价范文
2013/10/03 职场文书
记者岗位职责
2014/01/06 职场文书
在校大学生的职业生涯规划书
2014/03/14 职场文书
党课心得体会范文
2014/09/09 职场文书