js递归获取数组节点数据
需求:根据后端返回的树形数据对数据进行解析,取到符合要求的节点数据并返回
树形数据leftMenuList:
[
{
"id": "4c74f6018de1448fa7748171b96833eb",
"createDate": "2020-08-05 15:52:45",
"updateDate": "2021-12-21 15:25:06",
"parentIds": "0,1,",
"name": "首页",
"sort": 50,
"children": [],
"childNum": 0,
"href": "/home",
"icon": "el-icon-house",
"isShow": "1",
"type": "1",
"plateType": "0",
"backgroundType": "1",
"parentId": "1"
},{
"id": "27",
"createDate": "2013-05-27 08:00:00",
"updateDate": "2021-12-21 15:24:47",
"parentIds": "0,1,",
"name": "个人中心",
"sort": 170,
"children": [
{
"id": "95a6a82dc5fc4d07b46e5df57a0606a3",
"createDate": "2015-11-14 11:14:30",
"updateDate": "2021-12-21 14:50:05",
"parentIds": "0,1,27,",
"name": "我的信箱",
"sort": 30,
"children": [],
"childNum": 0,
"href": "/mailbox/index",
"icon": "fa fa-envelope",
"isShow": "1",
"type": "1",
"plateType": "3",
"backgroundType": "1",
"parentId": "27"
},
{
"id": "29",
"createDate": "2013-05-27 08:00:00",
"updateDate": "2021-12-21 15:13:49",
"parentIds": "0,1,27,",
"name": "个人信息",
"sort": 90,
"children": [],
"childNum": 0,
"href": "/sys/user/UserInfo",
"icon": "fa fa-blind",
"isShow": "1",
"type": "1",
"plateType": "3",
"backgroundType": "1",
"parentId": "27"
}
],
"childNum": 6,
"icon": "fa fa-user-secret",
"isShow": "1",
"type": "1",
"permission": "sys:personal:center",
"plateType": "3",
"backgroundType": "1",
"parentId": "1"
}
}
实现逻辑:
判断leftMenuList树形数据节点属性href值与给定值是否相同,如果相同就返回对应节点的数据
最开始用filter过滤数组并递归,实现代码如下:
menuListFilter (arr, name) {
return arr.filter(item => {
if(item.href === tab.name) {return true}
if(item.children.length>0){
return this.menuListFilter(item.children, tab)}
})
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name)
但是发现只能返回首层的数据,递归到第二层就无法返回了,
于是转换思路,直接循环数组并递归,并设置一个中间变量,临时存取结果,判断变量中有值就直接结束函数并返回,最后再返回一下menu,防止什么都取到不到的情况,实现代码如下:
menuListFilter (arr, name) {
// debugger
let menu = []
for(let i=0; i<arr.length; i++){
if(arr[i].href === name) {menu = arr[i]}
if(!menu&&arr[i].children.length>0){
menu = this.menuListFilter(arr[i].children, name)
}
if(menu) {return menu} //判断变量中有值就直接结束函数并返回
}
return menu
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name
这样写完后运行,发现始终返回的是空数组[],然后设置debugger打断点调试,逐行运行,才发现menu的判断值弄错了,在网上一搜才发现空数组[]的布尔值为true,然后修改了一下代码,判断menu.length的值,再次运行,正确实现了功能逻辑。
最后思考一下,既然for循环可以,forEach循环肯定也可以了,于是又优化了一下代码,最终实现代码如下:
menuListFilter (arr, name) {
let menu = []
arr.forEach(item => {
if(item.href === name) {menu = item}
if(menu.length==0&&item.children.length>0){
menu = this.menuListFilter(item.children, name)
}
if(menu.length>0) {return menu}
})
return menu
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name)