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 相关文章推荐
鼠标滚轮控制网页横向移动实现思路
Mar 22 Javascript
jquery为页面增加快捷键示例
Jan 31 Javascript
ionic由于使用了header和subheader导致被遮挡的问题的两种解决方法
Sep 22 Javascript
jQuery Mobile和HTML5开发App推广注册页
Nov 07 Javascript
自动适应iframe右边的高度
Dec 22 Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 Javascript
axios 处理 302 状态码的解决方法
Apr 10 Javascript
用ES6写全屏滚动插件的示例代码
May 02 Javascript
使用JS获取页面上的所有标签
Oct 18 Javascript
Nuxt.js实战和配置详解
Aug 05 Javascript
解决Antd Table组件表头不对齐的问题
Oct 27 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中在数据库中保存Checkbox数据(2)
2006/10/09 PHP
php 中文处理函数集合
2008/08/27 PHP
基于PHP的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
php新建文件自动编号的思路与实现
2011/06/27 PHP
PHP微信开发之模板消息回复
2016/06/24 PHP
PHP图形计数器程序显示网站用户浏览量
2016/07/20 PHP
PHP自动补全表单的两种方法
2017/03/06 PHP
jquery 批量上传图片实现代码
2010/01/28 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
JavaScript中对象property的读取和写入方法介绍
2014/12/30 Javascript
详解Angular中$cacheFactory缓存的使用
2016/08/19 Javascript
详谈JavaScript的闭包及应用
2017/01/17 Javascript
Javascript中构造函数要注意的一些坑
2017/01/23 Javascript
React Native如何消除启动时白屏的方法
2017/08/08 Javascript
jQuery实现用户信息表格的添加和删除功能
2017/09/12 jQuery
AngularJS 实现购物车全选反选功能
2017/10/24 Javascript
结合mint-ui移动端下拉加载实践方法总结
2017/11/08 Javascript
JS实现的集合去重,交集,并集,差集功能示例
2018/03/13 Javascript
详解vue-loader在项目中是如何配置的
2018/06/04 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
利用Python批量生成任意尺寸的图片
2016/08/29 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
python实现弹窗祝福效果
2019/04/07 Python
python字典排序的方法
2019/10/12 Python
Python实现word2Vec model过程解析
2019/12/16 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
台湾生鲜宅配:大口市集
2017/10/14 全球购物
Loreto Gallo英国:欧洲领先的在线药房
2021/01/21 全球购物
函授大专自我鉴定
2013/11/01 职场文书
公司开业庆典主持词
2014/03/21 职场文书
小学优秀教育工作者事迹材料
2014/05/09 职场文书
激励口号大全
2014/06/17 职场文书
2014年大学宣传部工作总结
2014/12/19 职场文书
介绍信的格式
2015/01/30 职场文书
2016新党章学习心得体会
2016/01/15 职场文书
Django debug为True时,css加载失败的解决方案
2021/04/24 Python