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实现的页面关键字密度查询代码
Dec 27 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
Apr 12 Javascript
js 使用form表单select类实现级联菜单效果
Dec 19 Javascript
js中return false(阻止)的用法
Aug 14 Javascript
JS取request值以及自动执行使用示例
Feb 24 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
Mar 15 Javascript
vue不通过路由直接获取url中参数的方法示例
Aug 24 Javascript
vue2.0使用swiper组件实现轮播的示例代码
Mar 03 Javascript
JavaScript设计模式之缓存代理模式原理与简单用法示例
Aug 07 Javascript
详解webpack4之splitchunksPlugin代码包分拆
Dec 04 Javascript
VUE项目中加载已保存的笔记实例方法
Sep 14 Javascript
JS数组的常用10种方法详解
May 08 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学习 计数器实例代码
2008/06/15 PHP
php4与php5的区别小结(配置异同)
2011/12/20 PHP
php中http_build_query 的一个问题
2012/03/25 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
Smarty最简单实现列表奇偶变色的方法
2015/07/01 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
PHP几个实用自定义函数小结
2016/01/25 PHP
PHP使用redis消息队列发布微博的方法示例
2017/06/22 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
JavaScript 放大镜 移动镜片效果代码
2011/05/09 Javascript
js onload事件不起作用示例分析
2013/10/09 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
ECMAScript 5严格模式(Strict Mode)介绍
2015/03/02 Javascript
jQuery插件实现文字无缝向上滚动效果代码
2016/02/25 Javascript
JS导出PDF插件的方法(支持中文、图片使用路径)
2016/07/12 Javascript
Bootstrap模态框插入视频的实现代码
2017/06/25 Javascript
vue组件实现可搜索下拉框扩展
2020/10/23 Javascript
Angular Material Icon使用详解
2018/11/07 Javascript
js canvas画布实现高斯模糊效果
2018/11/27 Javascript
bootstrap实现tab选项卡切换
2020/08/09 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
[04:29]2014DOTA2国际邀请赛 主赛事第三日TOPPLAY
2014/07/21 DOTA
Python运用于数据分析的简单教程
2015/03/27 Python
基于python 微信小程序之获取已存在模板消息列表
2019/08/05 Python
python+opencv实现移动侦测(帧差法)
2020/03/20 Python
欧缇丽美国官网:Caudalie美国
2016/12/31 全球购物
英国领先的互联网葡萄酒礼品商:Vintage Wine & Port
2019/05/24 全球购物
俄罗斯隐形眼镜和眼镜在线商店:Cronos
2020/06/02 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
大学生个人自我鉴定
2013/12/03 职场文书
技校个人求职信范文
2014/01/25 职场文书
户外亲子活动策划方案
2014/02/07 职场文书
邀请函模板
2015/02/02 职场文书
国庆阅兵观后感
2015/06/15 职场文书
初中同学会致辞
2015/08/01 职场文书
Java练习之潜艇小游戏的实现
2022/03/16 Java/Android