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 相关文章推荐
简体中文转换繁体中文(实现代码)
Dec 25 Javascript
JavaScript更改原始对象valueOf的方法
Mar 19 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
Aug 21 Javascript
Bootstrap每天必学之标签页(Tab)插件
Aug 09 Javascript
利用css+原生js制作简单的钟表
Apr 07 Javascript
详解Javascript中DOM的范围
Feb 13 Javascript
Vue精简版风格概述
Jan 30 Javascript
Bootstrap Paginator+PageHelper实现分页效果
Dec 29 Javascript
node全局变量__dirname与__filename的区别
Jan 14 Javascript
微信小程序中为什么使用var that=this
Aug 27 Javascript
解决vue-router路由拦截造成死循环问题
Aug 05 Javascript
Vue 3.0中jsx语法的使用
Nov 13 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实现下载生成某链接快捷方式的解决方法
2013/05/07 PHP
Javascript与PHP验证用户输入URL地址是否正确
2014/10/09 PHP
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
phpQuery采集网页实现代码实例
2020/04/02 PHP
javascript下操作css的float属性的特殊写法
2007/08/22 Javascript
Jquery实战_读书笔记1—选择jQuery
2010/01/22 Javascript
js遍历td tr等html元素
2012/12/13 Javascript
window.opener用法和用途实例介绍
2013/08/19 Javascript
Javascript倒计时页面跳转实例小结
2013/09/11 Javascript
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
Windows环境下npm install 报错: operation not permitted, rename的解决方法
2016/09/26 Javascript
详解PHP中pathinfo()函数导致的安全问题
2017/01/05 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
微信小程序中使用javascript 回调函数
2017/05/11 Javascript
浅谈ECMAScript6新特性之let、const
2017/08/02 Javascript
老生常谈js数据类型
2017/08/03 Javascript
Vue入门之animate过渡动画效果
2018/04/08 Javascript
JS复杂判断的更优雅写法代码详解
2018/11/07 Javascript
微信小程序自定义导航栏实例代码
2019/04/05 Javascript
详解Vue3中对VDOM的改进
2020/04/23 Javascript
JavaScript实现矩形块大小任意缩放
2020/08/25 Javascript
Node.js web 应用如何封装到Docker容器中
2020/09/01 Javascript
java直接调用python脚本的例子
2014/02/16 Python
Python中return语句用法实例分析
2015/08/04 Python
Python操作mongodb的9个步骤
2018/06/04 Python
Python Unittest根据不同测试环境跳过用例的方法
2018/12/16 Python
Python中pymysql 模块的使用详解
2019/08/12 Python
python给图像加上mask,并提取mask区域实例
2020/01/19 Python
python打印文件的前几行或最后几行教程
2020/02/13 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
美国牙科折扣计划:DentalPlans.com
2019/08/26 全球购物
土木工程毕业生推荐信
2013/10/28 职场文书
六五普法规划实施方案
2014/03/21 职场文书
申论倡议书范文
2014/05/13 职场文书
婚庆公司开业主持词
2015/06/30 职场文书
React如何使用axios请求数据并把数据渲染到组件
2022/08/05 Javascript