当我们需要将一维数组转换成一个多层结构的时候,最简单但是最慢的就是使用多个for循环嵌套,但是这样做有一些缺点,那就是效率太低,而且有多少层就需要用多少个for,现在我们可以使用一种高效的手段将一维的扁平数组转换成一个多层级的菜单结构。
一维数组中每一个元素必须要包含以下属性:
1.拥有一个唯一的id
2.拥有一个parent_id,这个id指向父级的id
扁平数组实例:
var menu_list = [{
id: '1',
menu_name: '设置',
menu_url: 'setting',
parent_id: 0
}, {
id: '1-1',
menu_name: '权限设置',
menu_url: 'setting.permission',
parent_id: '1'
}, {
id: '1-1-1',
menu_name: '用户管理列表',
menu_url: 'setting.permission.user_list',
parent_id: '1-1'
}, {
id: '1-1-2',
menu_name: '用户管理新增',
menu_url: 'setting.permission.user_add',
parent_id: '1-1'
}, {
id: '1-1-3',
menu_name: '角色管理列表',
menu_url: 'setting.permission.role_list',
parent_id: '1-1'
}, {
id: '1-2',
menu_name: '菜单设置',
menu_url: 'setting.menu',
parent_id: '1'
}, {
id: '1-2-1',
menu_name: '菜单列表',
menu_url: 'setting.menu.menu_list',
parent_id: '1-2'
}, {
id: '1-2-2',
menu_name: '菜单添加',
menu_url: 'setting.menu.menu_add',
parent_id: '1-2'
}, {
id: '2',
menu_name: '订单',
menu_url: 'order',
parent_id: 0
}, {
id: '2-1',
menu_name: '报单审核',
menu_url: 'order.orderreview',
parent_id: '2'
}, {
id: '2-2',
menu_name: '退款管理',
menu_url: 'order.refundmanagement',
parent_id: '2'
}
]
算法思想:
1.先将数组中的每一个节点都放在temp对象中(创建set)
即数组中有{id: ‘2-3’, parent_id: ‘2’,…}这样一个节点,需要将他放到temp中变成 ‘2-3’: {id: ‘2-3’, parent_id: ‘2’,…}这种JSON结构
2.直接遍历整个temp对象,通过temp[temp[i].parent].children[temp[i].id]=temp[i];将当前节点与父节点进行连接。这是因为我们保证了父节点一定在子节点前,那么当子节点出现的时候直接可以用temp[temp[i].parent_id]来查找父节点的children对象中添加一个引用即可
function buildtree(list){
let temp={};
let tree={};
for(let i in list){
temp[list[i].id]=list[i];
}
for(let i in temp){
// 如果有父级id
if(temp[i].parent_id){
if(!temp[temp[i].parent_id].children){
temp[temp[i].parent_id].children=new Object();
}
// 将父节点与子节点连接起来
temp[temp[i].parent_id].children[temp[i].id]=temp[i];
}else{
tree[temp[i].id]=temp[i];
}
}
return tree;
}