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 FormatNumber函数实现方法
Dec 30 Javascript
三级下拉菜单的js实现代码
May 23 Javascript
jQuery中ajax和post处理json的不同示例对比
Nov 02 Javascript
JS中用三种方式实现导航菜单中的二级下拉菜单
Oct 31 Javascript
AngularJS实现动态添加Option的方法
May 17 Javascript
前端构建工具之gulp的语法教程
Jun 12 Javascript
Require.js的基本用法详解
Jul 03 Javascript
JavaScript变量类型以及变量作用域详解
Aug 14 Javascript
Node.js从字符串生成文件流的实现方法
Aug 18 Javascript
JavaScript算法学习之冒泡排序和选择排序
Nov 02 Javascript
JQuery中DOM节点的操作与访问方法实例分析
Dec 23 jQuery
Vue3实现简易音乐播放器组件
Aug 14 Vue.js
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
Window下PHP三种运行方式图文详解
2013/06/11 PHP
显示程序执行时间php函数代码
2013/08/29 PHP
PHP实现电商订单自动确认收货redis队列
2017/05/17 PHP
Dom操作之兼容技巧分享
2011/09/20 Javascript
JQuery操作单选按钮以及复选按钮示例
2013/09/23 Javascript
JS中typeof与instanceof之间的区别总结
2013/11/14 Javascript
jquery控制背景音乐开关与自动播放提示音的方法
2015/02/06 Javascript
jQuery移动web开发中的页面初始化与加载事件
2015/12/03 Javascript
jQuery中 $ 符号的冲突问题及解决方案
2016/11/04 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
js简易版购物车功能
2017/06/17 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
JS同步、异步、延迟加载的方法
2018/05/05 Javascript
使用node.js实现微信小程序实时聊天功能
2018/08/13 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
一秒学会微信小程序制作table表格
2019/02/14 Javascript
python使用xmlrpc实例讲解
2013/12/17 Python
基于Python实现的百度贴吧网络爬虫实例
2015/04/17 Python
在Python操作时间和日期之asctime()方法的使用
2015/05/22 Python
python 3.7.0 下pillow安装方法
2018/08/27 Python
selenium处理元素定位点击无效问题
2019/06/12 Python
利用Python模拟登录pastebin.com的实现方法
2019/07/12 Python
python实现京东订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python Django框架模板渲染功能示例
2019/11/08 Python
python实现批量转换图片为黑白
2020/06/16 Python
浅谈HTML5 defer和async的区别
2016/06/07 HTML / CSS
详解基于 Canvas 手撸一个六边形能力图
2019/09/02 HTML / CSS
Baracuta官方网站:Harrington夹克,G9,G4,G10等
2018/03/06 全球购物
医大实习自我鉴定
2013/12/07 职场文书
函授毕业个人自我评价
2014/02/20 职场文书
创先争优演讲稿
2014/09/15 职场文书
2015年党风廉政建设责任书
2015/01/29 职场文书
升职自荐信范文
2015/03/27 职场文书
毕业论文答辩开场白和结束语
2015/05/27 职场文书
创业者如何撰写出一份打动投资人的商业计划书?
2019/07/02 职场文书
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技