JSON LIST转树形结构

423

问题背景

业务功能中时常有这样的场景,数据结构是LIST结构,包含id,pid,name三个基本属性,我们有时候需要将这种数据结构转化为树形结构,在某些场景更加实用。比方说组织架构数据,菜单数据等。

处理方式

以组织架构数据为例,代码以C#为例。

组织架构数据

一般类似这种jsonString


[{
	"name": "洞头区",
	"parentId": "3303",
	"deptId": "330322"
}, {
	"name": "苍南县",
	"parentId": "3303",
	"deptId": "330327"
}, {
	"name": "文成县",
	"parentId": "3303",
	"deptId": "330328"
}, {
	"name": "瑞安市",
	"parentId": "3303",
	"deptId": "330381"
}, {
	"name": "乐清市",
	"parentId": "3303",
	"deptId": "330382"
}, ...]

组织架构类

ok,我们可以根据上面的数据结构构造组织架构类


public class DeptNode {

    public string deptId { get; set; }

    public string parentId { get; set; }

    public string name { get; set; }

    public List<DeptNode> depts { get; set; }
}

生成树之事先知道根节点

假设我们事先知道根节点,我们一般采用递归方式去做。


static void Main(string[] args){
    DeptNode rootNode = new DeptNode
    {
        deptId = "33",
        parentId = "0",
        name = "我是根节点",
        depts = new List<DeptNode>()
    };
    string jsonString = "[{}]";
    List<DeptNode> depts = JsonConvert.DeserializeObject<List<DeptNode>>(jsonString);
    rootNode = CreateTree();
}
public DeptNode CreateTree(List<DeptNode> depts, DeptNode node)
{

    foreach (DeptNode dept in depts)
    {
        if (dept.parentId == node.deptId)
        {
            if(node.depts == null)
            {
                node.depts = new List<DeptNode>();
            }
            CreateTree(depts, dept);
            node.depts.Add(dept);
        }
    }

    return node;
}

事先不知道根节点

待更新
组织结构树形结构.jpg

其他常见情况

我要检查LIST数据中是否有非法节点

什么是非法节点?即父节点不存在。
检测方式:


//检查无父节点的节点
public void GetNoParentNode(List<DeptNode> depts,DeptNode treeNode)
{
    foreach (var dept in depts)
    {
        bool exist = CheckIfNodeExist(treeNode, dept.deptId);
        if (!exist)
        {
            Console.WriteLine(JsonConvert.SerializeObject(dept));
        }
    }
}
//检测节点是否存在于树里
public bool CheckIfNodeExist(DeptNode treeNode, string deptId)
{
    bool exist = false;

    if(treeNode.deptId == deptId)
    {
        exist = true;
    }

    foreach (DeptNode dept in treeNode.depts)
    {
        if (dept.deptId == deptId)
        {
            exist = true;
        }
        else
        {
            if(dept.depts != null)
            {
                if(CheckIfNodeExist(dept, deptId))
                {
                    exist = true;
                }
            }
        }
    }

    return exist;
}