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 相关文章推荐
背景音乐每次刷新都可以自动更换
Feb 01 Javascript
JQuery 插件制作实践 xMarquee插件V1.0
Apr 02 Javascript
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
Feb 27 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
Apr 12 Javascript
javascript实现十秒钟后注册按钮可点击的方法
May 13 Javascript
AngularJS中实现动画效果的方法
Jul 28 Javascript
详解vue中axios的封装
Jul 18 Javascript
jQuery实现表单动态添加数据并提交的方法
Jul 19 jQuery
Vuejs监听vuex中值的变化的方法示例
Dec 02 Javascript
bootstrap datepicker的基本使用教程
Jul 09 Javascript
Vue.use()在new Vue() 之前使用的原因浅析
Aug 26 Javascript
JavaScript代理模式原理与用法实例详解
Mar 10 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
咖啡是不是喝了会上瘾?咖啡是必须品吗!
2021/03/04 新手入门
PHP实现查询两个数组中不同元素的方法
2016/02/23 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
2016/09/19 PHP
如何获取select下拉框的值(option没有及有value属性)
2013/11/08 Javascript
jquery简单实现鼠标经过导航条改变背景图
2013/12/17 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
谈谈我对JavaScript DOM事件的理解
2015/12/18 Javascript
JS中实现函数return多个返回值的实例
2017/02/21 Javascript
vuex actions传递多参数的处理方法
2018/09/18 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
微信小程序实现打卡日历功能
2020/09/21 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
Vue引入Stylus知识点总结
2020/01/16 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
[01:09:40]Newbee vs Pain 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
详解Python中的循环语句的用法
2015/04/09 Python
Python 字典与字符串的互转实例
2017/01/13 Python
python数据预处理之数据标准化的几种处理方式
2019/07/17 Python
Python数学形态学实例分析
2019/09/06 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
python 已知平行四边形三个点,求第四个点的案例
2020/04/12 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
优秀毕业生就业推荐信
2014/05/22 职场文书
服装设计师求职信
2014/06/04 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
2014年少先队工作总结
2014/12/03 职场文书
2015年党员发展工作总结
2015/05/13 职场文书
山楂树之恋观后感
2015/06/11 职场文书
《狼牙山五壮士》教学反思
2016/02/17 职场文书
Mysql效率优化定位较低sql的两种方式
2021/05/26 MySQL
如何正确理解python装饰器
2021/06/15 Python