数组reduce方法的好处(JS使用reduce方法处理树形结构数据)
类别:编程学习 浏览量:2001
时间:2022-04-03 11:03:57 数组reduce方法的好处
JS使用reduce方法处理树形结构数据目录
- 定义
- 语法
- 实例
- 1. 没有传递初始值init
- 2. 传递初始值的情况下
- 3. 数组去重
- 4. 利用 reduce 对数组中的 Object 对象进行分组及合并
- 5. 利用 reduce 处理菜单后端返回的菜单结构
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
reduce() 与forEach()、map()、filter()这些方法一样,也会对数组中的每一项进行遍历,但是reduce() 可以将遍历的前一个数组项产生的结果与当前遍历项进行运算。
语法array.reduce(function(prev, cur, index, array){ ... }, init);
回调函数中的参数:
- prev 必需。表示调用回调时的返回值,或者初始值 init。
- cur 必需。表示当前元素。
- index 可选。表示当前元素的索引。
- array 表示原数组。
- init 可选。初始值,作为第一次调用回调函数的第一个参数。
其中常用参数:prev 和 cur
注意:回调函数第一次执行时,prev和cur的取值有两种情况:如果调用reduce()时提供了初始值init,prev取init值,cur取数组中的第一个值,此时索引从0开始;如果没有提供初始值init,则prev取数组中的第一个值,cur取数组中的第二个值,此时索引从1开始。
实例1. 没有传递初始值init
const arr = [1, 3, 5, 7] arr.reduce(function(prev, cur, index, arr){ console.log(prev, cur, index) return prev + cur })
每次调用的参数和返回值如下表:
callback | prev | cur | index | array | return value |
---|---|---|---|---|---|
第1次 | 1 | 3 | 1 | [1, 3, 5, 7] | 4 |
第2次 | 4 | 5 | 2 | [1, 3, 5, 7] | 9 |
第3次 | 9 | 7 | 3 | [1, 3, 5, 7] | 16 |
因为没有传入初始值,所以索引是从1开始,callback被调用三次,开始时prev的值为数组第一项1,cur的值为3,相加之后返回值4作为下一轮回调的prev值,然后继续下一轮的回调,直至完成后返回。
2. 传递初始值的情况下
const arr = [1, 3, 5, 7] arr.reduce(function(prev, cur, index, arr){ console.log(prev, cur, index) return prev + cur }, 10)
每次调用的参数和返回值如下表:
callback | prev | cur | index | array | return value |
---|---|---|---|---|---|
第1次 | 10 | 1 | 0 | [1, 3, 5, 7] | 11 |
第2次 | 11 | 3 | 1 | [1, 3, 5, 7] | 14 |
第3次 | 14 | 5 | 2 | [1, 3, 5, 7] | 19 |
第4次 | 19 | 7 | 3 | [1, 3, 5, 7] | 26 |
3. 数组去重
const arr = ['ab', 'v', 'd', 'ab', 'h', 'e', 'dc', 'e', 'e', 'f'] const newArr = arr.reduce(function(prev, cur){ !prev.includes(cur) && prev.push(cur) return prev }, []) console.log(newArr) // ["ab", "v", "d", "h", "e", "dc", "f"]
执行的步骤如下:
- 初始化一个空数组
- 第一次调用时,prev 为初始值即空数组,cur 为数组中的第一项 arr[1],然后在 prev 中查找 cur 是否已经存在,如果不存在就将该项添加到 prev 中,并 prev 返回进入下一次回调
- 第二次回调时,prev 为第一次的返回值,cur 为数组中的第二项 arr[2],然后在 prev 中查找 cur 是否已经存在,如果不存在就将该项添加到 prev 中,并 prev 返回进入下一次回调
- 最后将 prev 这个数组返回
4. 利用 reduce 对数组中的 Object 对象进行分组及合并
//从后台获取的对象数组,根据对象的type进行分组合并成tree树形展示数据 const dataArr = [ { type: '治理层', name: 'hive_82', reserve: '2', id: 1 }, { type: '原始数据层', name: 'qwe', reserve: '1', id: 2 }, { type: '贴源层', name: 'mysql_exchangis', reserve: '3', id: 3 }, { type: '治理层', name: 'links_188', reserve: '1', id: 4 }, { type: '贴源层', name: 'mysql_ces', reserve: '2', id: 5 } ] const treeData = dataArr.reduce((cur, next) => { const obj = cur.find(curItem => curItem.label === next.type) if (obj) { if (obj.children.indexOf(next.id) === -1) { //去重处理 obj.children.push({ ...next, label: next.name }) } } else { const newObj = { label: next.type, children: [{ ...next, label: next.name }] } cur.push(newObj) } return cur }, []) // 合并后的结果: treeData = [ { label: '治理层', children: [ { type: '治理层', name: 'hive_82', reserve: '2', id: 1, label: 'hive_82' }, { type: '治理层', name: 'links_188', reserve: '1', id: 4, label: 'links_188' } ] }, { label: '原始数据层', children: [ { type: '原始数据层', name: 'qwe', reserve: '1', id: 2, label: 'qwe' } ] }, { label: '贴源层', children: [ { type: '贴源层', name: 'mysql_exchangis', reserve: '3', id: 3, label: 'mysql_exchangis' }, { type: '治理层', name: 'mysql_ces', reserve: '2', id: 5, label: 'mysql_ces' } ] } ]
5. 利用 reduce 处理菜单后端返回的菜单结构
需要根据 parentId 将这些数据转换成层级结构。
方法一:
const dataArr = [ {id: '18', name: '重置密码', parentId: '30',parentName: '用户管理'}, {id: '13', name: '审计日志', parentId: '29', parentName: '系统管理'}, {id: '29', name: '系统管理', parentId: '0', parentName: null}, {id: '14', name: '修改', parentId: '33', parentName: '部门管理'}, {id: '2', name: '用户列表', parentId: '30', parentName: '用户管理'}, {id: '30', name: '用户管理', parentId: '29', parentName: '系统管理'}, {id: '33', name: '部门管理', parentId: '0', parentName: null}, {id: '37', name: '添加用户', parentId: '30', parentName: '用户管理'}, {id: '6', name: '添加', parentId: '33', parentName: '部门管理'}, {id: '7',name: '删除', parentId: '33', parentName: '部门管理'} ] //创建菜单id的映射关系 const idMapping = dataArr.reduce((prev, next, i) => { prev[next.id] = i return prev }, {}) const treeData = [] dataArr.map(el => { // 一级菜单 if (el.parentId === '0') { treeData.push(el) return } // 通过映射找到父元素 const parentEl = dataArr[idMapping[el.parentId]] // 把当前元素添加到父元素的`children`数组中 parentEl.children = [...(parentEl.children || []), el] }) console.log(treeData)
方法二:
//根据parentId创建映射关系 const result = dataArr.reduce((prev, next) => { prev[next.parentId] ? prev[next.parentId].push(next) : prev[next.parentId] = [next]; return prev; }, {}); Object.keys(result).map(key => { result[key].map((item, i) => { result[item.id] ? item.children = result[item.id] : '' }); }) this.treeData = result[0] console.log(treeData)
还可以通过递归的方法来实现,具体就不赘述了
最后生成的数据结构如下图所示:
以上就是JS使用reduce()方法处理树形结构数据的详细内容,更多关于JS的资料请关注开心学习网其它相关文章!
您可能感兴趣
- js中Attribute和Property区别
- js三级联动列表(基于JavaScript实现年月日三级联动)
- js 定时切换图片(JavaScript定时器实现无缝滚动图片)
- js 全局变量与局部变量
- js中alert相关知识点(js中getBoundingClientRect 方法案例详解)
- js的遍历数组方法(JS中数组常用的循环遍历你会几种)
- js搜索功能的实现(前端JavaScript实现本地模糊搜索功能的方法实例)
- js轮播图片(JS实现简单图片轮播效果)
- 火狐查看json数据
- pandasjson格式(对pandas处理json数据的方法详解)
- 通过js获取Url的参数值
- ExtJs 中Viewport 的使用
- Js如何判断浏览器类型和版本
- js防抖用法(JavaScript的防抖和节流案例)
- JSON中的特殊字符
- js弹出框代码(js实现自动锁屏功能)
- 《精英律师》剧照首曝光,实力演员飙戏,演绎律政职场百态(精英律师剧照首曝光)
- 靳东领衔打造高精职场 新丽出品《精英律师》曝定妆照(靳东领衔打造高精职场)
- 靳东新剧《精英律师》定档,众星云集,这剧可追(靳东新剧精英律师定档)
- 精英律师 廖佳敏封印恋情曝光,顾婕马失前蹄 你个老不死的(廖佳敏封印恋情曝光)
- 以家人之名广受好评,剧情生动引起观众共鸣,演员张新成圈粉无数(以家人之名广受好评)
- 三兄妹感情再遇波折,人设接连崩塌 《以家人之名》剧情猜不透(三兄妹感情再遇波折)
热门推荐
- mysql怎么做教材信息管理系统(python+mysql实现学生信息查询系统)
- html怎么去除css边框(Html/CSS前端实现文字边框阴影效果)
- docker容器默认内存大小(Docker 修改docker存储位置 修改容器镜像大小限制操作)
- mysql查看执行计划
- idea社区版使用tomcat部署项目(基于IDEA部署Tomcat服务器的步骤详解)
- ssis项目部署配置(基于SSIS 事件的向上传递详解)
- php怎么设计状态模式(php设计模式之观察者模式定义与用法经典示例)
- mysql创建用户并给用户授权(MySQL 主从复制中创建复制用户的时机探讨)
- html5 canvas 性能(基于html5 canvas做批改作业的小插件)
- 在linux中实现可加载的内核模块(Linux实现驱动模块传参过程解析)