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 相关文章推荐
js弹窗代码 可以指定弹出间隔
Jul 03 Javascript
javascript算法学习(直接插入排序)
Apr 12 Javascript
js中escape对应的C#解码函数 UrlDecode
Dec 16 Javascript
JS获取浏览器版本及名称实现函数
Apr 02 Javascript
自己动手写的jquery分页控件(非常简单实用)
Oct 28 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
Mar 01 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
Jul 03 Javascript
vue中的非父子间的通讯问题简单的实例代码
Jul 19 Javascript
Vue自定义事件(详解)
Aug 19 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
Aug 01 Javascript
微信小程序制作表格的方法
Feb 14 Javascript
Canvas三种动态画圆实现方法说明(小结)
Apr 16 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
PHP脚本的10个技巧(5)
2006/10/09 PHP
PHP笔记之:日期函数的使用介绍
2013/04/24 PHP
php根据身份证号码计算年龄的实例代码
2014/01/18 PHP
PHP文件读取功能的应用实例
2015/05/08 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
php常用字符串查找函数strstr()与strpos()实例分析
2019/06/21 PHP
php中isset与empty函数的困惑与用法分析
2019/07/05 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
让textarea控件的滚动条怎是位与最下方
2007/04/20 Javascript
JavaScript 验证码的实例代码(附效果图)
2013/03/22 Javascript
JavaScript事件代理和委托详解
2016/04/08 Javascript
jquery 实现回车登录详解及实例代码
2016/10/23 Javascript
js 能实现监听F5页面刷新子iframe 而父页面不刷新的方法
2016/11/09 Javascript
JavaScript实现打砖块游戏
2020/02/25 Javascript
vue+vant实现购物车全选和反选功能
2020/11/17 Vue.js
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 KG VS OG
2018/03/30 DOTA
使用PDB模式调试Python程序介绍
2015/04/05 Python
Python3编程实现获取阿里云ECS实例及监控的方法
2017/08/18 Python
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
详解Django的model查询操作与查询性能优化
2018/10/16 Python
如何在Python中实现goto语句的方法
2019/05/18 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
python实现H2O中的随机森林算法介绍及其项目实战
2019/08/29 Python
Python 实现Numpy中找出array中最大值所对应的行和列
2019/11/26 Python
使用pytorch实现论文中的unet网络
2020/06/24 Python
python文件及目录操作代码汇总
2020/07/08 Python
js实现移动端H5页面手指滑动刻度尺功能
2017/11/16 HTML / CSS
美国女鞋品牌:naturalizer(娜然)
2016/08/01 全球购物
经贸专业毕业生求职信
2014/03/23 职场文书
文化建设工作方案
2014/05/12 职场文书
给老师的感谢信
2015/01/20 职场文书
年会邀请函范文
2015/01/30 职场文书
4S店收银员岗位职责
2015/04/07 职场文书
Java Socket实现Redis客户端的详细说明
2021/05/26 Redis
一文了解MYSQL三大范式和表约束
2022/04/03 MySQL
Python经常使用的一些内置函数
2022/04/11 Python