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 相关文章推荐
海量经典的jQuery插件集合
Jan 12 Javascript
原来Jquery.load的方法可以一直load下去
Mar 28 Javascript
JavaScript代码编写中各种各样的坑和填坑方法
Jun 06 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
Oct 02 Javascript
Jquery on方法绑定事件后执行多次的解决方法
Jun 02 Javascript
JS经典正则表达式笔试题汇总
Dec 15 Javascript
EasyUI折叠表格层次显示detailview详解及实例
Dec 28 Javascript
微信小程序开发教程之增加mixin扩展
Aug 09 Javascript
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
Sep 12 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
May 03 Javascript
微信小程序实现留言功能
Oct 31 Javascript
vue中进行微博分享的实例讲解
Oct 14 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以mysqli方式连接类完整代码实例
2014/07/15 PHP
php图片添加水印例子
2016/07/20 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
javascript下给元素添加事件的方法与代码
2007/08/13 Javascript
JQuery菜单效果的两个实例讲解(3)
2015/09/17 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
2016/05/04 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
2016/06/28 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
微信小程序 表单Form实例详解(附源码)
2016/12/22 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
js实现从左向右滑动式轮播图效果
2017/07/07 Javascript
JavaScript创建对象的七种方式全面总结
2017/08/21 Javascript
如何解决vue2.0下IE浏览器白屏问题
2018/09/13 Javascript
微信小程序之裁剪图片成圆形的实现代码
2018/10/11 Javascript
javascript实现的字符串转换成数组操作示例
2019/06/13 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
vuejs移动端实现div拖拽移动
2019/07/25 Javascript
深入浅析vue中cross-env的使用
2019/09/12 Javascript
java和js实现的洗牌小程序
2019/09/30 Javascript
vue 使用localstorage实现面包屑的操作
2020/11/16 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
2020/11/18 Vue.js
深入分析在Python模块顶层运行的代码引起的一个Bug
2014/07/04 Python
在Python中操作文件之truncate()方法的使用教程
2015/05/25 Python
Python3 加密(hashlib和hmac)模块的实现
2017/11/23 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
Python openpyxl模块原理及用法解析
2020/01/19 Python
浅谈numpy中函数resize与reshape,ravel与flatten的区别
2020/06/18 Python
详解利用canvas实现环形进度条的方法
2019/06/12 HTML / CSS
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
学校法制宣传月活动总结
2014/07/03 职场文书
学习党的群众路线教育实践活动心得体会范文
2014/11/03 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
优秀志愿者感言
2015/08/01 职场文书
安全主题班会教案
2015/08/12 职场文书
公司年会晚会开幕词
2019/04/02 职场文书