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 相关文章推荐
Prototype使用指南之base.js
Jan 10 Javascript
响应鼠标变换表格背景或者颜色的代码
Mar 30 Javascript
jquery实现html页面 div 假分页有原理有代码
Sep 06 Javascript
详解JavaScript的策略模式编程
Jun 24 Javascript
高性能JavaScript 重排与重绘(2)
Aug 11 Javascript
JS图片放大效果简单实现代码
Sep 08 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
Dec 02 Javascript
JS判断一个数是否是水仙花数
Jun 11 Javascript
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
vue实现微信分享功能
Nov 28 Javascript
js数据类型转换与流程控制操作实例分析
Dec 18 Javascript
vue video和vue-video-player实现视频铺满教程
Oct 30 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 创建标签云函数代码
2010/05/26 PHP
php去除换行符的方法小结(PHP_EOL变量的使用)
2013/02/16 PHP
php读取3389的脚本
2014/05/06 PHP
ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单
2014/05/15 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
PHP实现简单搜歌的方法
2015/07/28 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
jquery tools之tabs 选项卡/页签
2009/07/25 Javascript
jQeury淡入淡出需要注意的问题
2010/09/08 Javascript
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
node.js中的buffer.slice方法使用说明
2014/12/10 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
用js编写的简单的计算器代码程序
2015/08/04 Javascript
javascript图片预加载完整实例
2015/12/10 Javascript
JavaScript实现省市联动过程中bug的解决方法
2017/12/04 Javascript
JavaScript伪数组用法实例分析
2017/12/22 Javascript
深入浅析JSONAPI在PHP中的应用
2017/12/24 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
Vue 之孙组件向爷组件通信的实现
2019/04/23 Javascript
微信小程序文章详情页跳转案例详解
2019/07/09 Javascript
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
详解Python Socket网络编程
2016/01/05 Python
使用Python批量修改文件名的代码实例
2019/01/24 Python
使用pip安装python库的多种方式
2019/07/31 Python
python3 深浅copy对比详解
2019/08/12 Python
Python全栈之列表数据类型详解
2019/10/01 Python
python多进程重复加载的解决方式
2019/12/13 Python
在python中利用dict转json按输入顺序输出内容方式
2020/02/27 Python
Python读取图像并显示灰度图的实现
2020/12/01 Python
html5 标签
2009/07/16 HTML / CSS
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
淘宝客服自我总结鉴定
2014/01/25 职场文书
2014年环保局工作总结
2014/12/11 职场文书
2015年试用期自我评价范文
2015/03/10 职场文书
python将图片转为矢量图的方法步骤
2021/03/30 Python