js递归遍历dom树、数组扁平化
1. 遍历dom树
//数据
var data = [{id: 1,name: "办公管理",pid: 0},
{id: 2,name: "请假申请",pid: 1},
{id: 3,name: "出差申请",pid: 1},
{id: 4,name: "请假记录",pid: 2},
{id: 5,name: "系统设置",pid: 0},
{id: 6,name: "权限管理",pid: 5},
{id: 7,name: "用户角色",pid: 6},
{id: 8,name: "菜单设置",pid: 6},
];
//第一种方法
function getTree1(data) {
const root = data.filter(item => {
return item.pid === 0
})
root.forEach(root => {
root.children = data.filter(item => {
return item.pid === root.id
})
if (root.children && root.children.length) {
root.children.forEach(item => {
const subChildren = data.filter(subItem => {
return subItem.pid === item.id
})
item.children = subChildren
})
}
})
return root
}
console.log(getTree1(data))
//第二种
function getTree2(data, id) {
// 判断传入的数据是否是数组
if (Object.prototype.toString.call(data) !== '[object Array]') return
const root = data.filter(item => item.pid === id)
const list = []
// 遍历跟节点
root.forEach(item => {
const obj = {...item,children: getTree2(data, item.id) } // 递归方法,自己调用自己
list.push(obj)
})
return list
}
console.log(getTree2(data, 0))
//结果
[
{
"id":1,
"name":"办公管理",
"pid":0,
"children":[
{
"id":2,
"name":"请假申请",
"pid":1,
"children":[
{
"id":4,
"name":"请假记录",
"pid":2,
"children":[]
}
]
},
{
"id":3,
"name":"出差申请",
"pid":1,
"children":[]
}
]
},
{
"id":5,
"name":"系统设置",
"pid":0,
"children":[
{
"id":6,
"name":"权限管理",
"pid":5,
"children":[
{
"id":7,
"name":"用户角色",
"pid":6,
"children":[]
},
{
"id":8,
"name":"菜单设置",
"pid":6,
"children":[]
}
]
}
]
}
]
- 扁平化数组
[1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]
递归
//递归的遍历每一项,若为数组则继续遍历,否则concat
function flatten(arr) {
var res = [];
arr.map(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
reduce
//遍历数组每一项,若值为数组则递归遍历,否则concat。
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
//reduce是数组的一种方法,它接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
//reduce包含两个参数:回调函数,传给total的初始值
// 求数组的各项值相加的和:
arr.reduce((total, item)=> { // total为之前的计算结果,item为数组的各项值
return total + item;
}, 0);
toString & split
//调用数组的toString方法,将数组变为字符串然后再用split分割还原为数组
function flatten(arr) {
return arr.toString().split(',').map(function(item) {
return Number(item);
})
}
//因为split分割后形成的数组的每一项值为字符串,所以需要用一个map方法遍历数组将其每一项转换为数值型
join & split
function flatten(arr) {
return arr.join(',').split(',').map(function(item) {
return parseInt(item);
})
}
扩展运算符
//es6的扩展运算符能将二维数组变为一维
[].concat(…[1, 2, 3, [4, 5]]); [1, 2, 3,4, 5]
//根据这个结果我们可以做一个遍历,若arr中含有数组则使用一次扩展运算符,直至没有为止。
function flatten(arr) {
while(arr.some(item=>Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
小结
写了五种但核心也只有一个:
遍历数组arr,若arr[i]为数组则递归遍历,直至arr[i]不为数组然后与之前的结果concat。
版权声明:本文为LRuiXin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。