Nodejs与树形结构
常见的树形结构使用场景,一般层级不会特别深,节点不会特别多,比如菜单、组织架构等,所以这里不会顾虑性能问题。
在上述观点的基础上,个人认为存储父节点ID的设计,最为简洁直观,接近完美。
但是,这种结构不易取得通常想要的结构,比如。。。
所以,要解决两个问题:
1.转化为树形json
2.便捷的方法找到某节点所有下级节点或所有上级节点
转化为树形json数据
const all = [
{id: 1, name: 'n1', parent_id: 0},
{id: 2, name: 'n2', parent_id: 0},
{id: 3, name: 'n3', parent_id: 0},
{id: 4, name: 'n4', parent_id: 1},
{id: 5, name: 'n5', parent_id: 1},
{id: 6, name: 'n6', parent_id: 2},
{id: 7, name: 'n7', parent_id: 3},
{id: 8, name: 'n8', parent_id: 4},
{id: 9, name: 'n9', parent_id: 8}
]
/**
* 将直接从数据库查出的每个节点只存父节点ID的数据,转为更直观的json树形数据。
* 1.all中必须包含根节点,形似[{},{},{}]
* 2.all中每个元素至少有id和parent_id两个字段
* @param all 需要转化的节点原始数据
* @return 树形结构json
*/
exports.convertTree = all => {
const tmp = {};
for (let i = 0; i < all.length; i++) {
const item = all[i];
if (!tmp[item.id]) {
tmp[item.id] = {};
}
// 根据引用类型数据特性,所有tmp的节点,key键为tmp[item.id]的数据都是指向同一堆地址,修改一个{tmp[item.id]:xxx},其他的也会一起变。
for (const key in item) {
if (item.hasOwnProperty(key)) tmp[item.id][key] = item[key];
}
if (!('children' in tmp[item.id])) tmp[item.id].children = [];
if (tmp[item.father_id]) {
tmp[item.father_id].children.push(tmp[item.id]);
} else {
tmp[item.father_id] = {children: [tmp[item.id]]};
}
}
return tmp[0].children;
};
找到某节点所有下级节点
本文使用mysql的自定义函数功能实现,代码如下:
BEGIN #根据父节点找出所有子节点 DECLARE temp VARCHAR(1000); DECLARE tempchd VARCHAR(1000); SET temp = ''; SET tempchd =CAST(rootId AS CHAR); WHILE tempchd IS NOT NULL DO SET temp = CONCAT(temp,',',tempchd); SELECT GROUP_CONCAT(id) INTO tempchd FROM manage_menu WHERE FIND_IN_SET(father_id,tempChd)>0; END WHILE; SET temp=SUBSTR(temp FROM 2); RETURN temp; END
找到某节点所有下级节点
本文使用mysql的自定义函数功能实现,代码如下:
BEGIN #根据子节点节点找出所有父节点 DECLARE tempfat varchar(100) default ''; DECLARE temp varchar(1000) default childId; WHILE childId is not null do SET tempfat =(SELECT father_id FROM manage_menu WHERE id = childId); IF tempfat is not null THEN SET temp = concat(temp, ',', tempfat); SET childId = tempfat; ELSE SET childId = tempfat; END IF; END WHILE; SET temp=SUBSTR(temp FROM 1 FOR length(temp)-2); return temp; END