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 防止刷新,后退,关闭
Aug 07 Javascript
js 链式延迟执行DOME
Jan 04 Javascript
JavaScript模板入门介绍
Sep 26 Javascript
jquery通过visible来判断标签是否显示或隐藏
May 08 Javascript
了解Javascript的模块化开发
Mar 02 Javascript
JavaScript DOM元素尺寸和位置
Apr 13 Javascript
javascript HTML5文件上传FileReader API
Mar 27 Javascript
javascript使用btoa和atob来进行Base64转码和解码
Mar 20 Javascript
Angular2环境搭建具体操作步骤(推荐)
Aug 04 Javascript
JS和jQuery通过this获取html标签中的属性值(实例代码)
Sep 11 jQuery
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
Jul 30 Javascript
深入理解Vue 组件之间传值
Aug 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
2020最新CPU的性能排名
2020/04/02 数码科技
玩转图像函数库―常见图形操作
2006/09/03 PHP
PHPThumb图片处理实例
2014/05/03 PHP
php中实现用数组妩媚地生成要执行的sql语句
2015/07/10 PHP
PHP记录和读取JSON格式日志文件
2016/07/07 PHP
一个简单的JavaScript数据缓存系统实现代码
2010/10/24 Javascript
Jquery 表单验证类介绍与实例
2013/06/09 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
javascript继承的六大模式小结
2015/04/13 Javascript
jQuery实现鼠标划过修改样式的方法
2015/04/14 Javascript
再谈JavaScript线程
2015/07/10 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
2015/08/27 Javascript
不得不分享的JavaScript常用方法函数集(上)
2015/12/23 Javascript
javascript中闭包(Closure)详解
2016/01/06 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
浅谈jQuery hover(over, out)事件函数
2016/12/03 Javascript
利用Angular.js编写公共提示模块的方法教程
2017/05/28 Javascript
JavaScript对象拷贝与赋值操作实例分析
2018/12/10 Javascript
js实现简单抽奖功能
2020/11/24 Javascript
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
python统计字符的个数代码实例
2020/02/07 Python
Python常用断言函数实例汇总
2020/11/30 Python
Mytheresa中国官网:德国时尚奢侈品商城
2017/08/04 全球购物
几个人围成一圈的问题
2013/09/26 面试题
Linux常见面试题
2016/10/04 面试题
用Python匹配HTML tag的时候,<.*>和<.*?>有什么区别
2012/11/04 面试题
总经理助理岗位职责
2013/11/08 职场文书
家居设计专业个人自荐信范文
2013/11/26 职场文书
2014年校长工作总结
2014/12/11 职场文书
雾霾停课通知
2015/04/24 职场文书
大学生创业,为什么都会选择快餐饮?
2019/08/08 职场文书
护理专业毕业自我鉴定
2019/08/12 职场文书
详解MySQL 联合查询优化机制
2021/05/10 MySQL