树形结构数据完美解决方案

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

 

posted @ 2018-12-10 15:09  土拉发子  Views(1514)  Comments(0Edit  收藏  举报