C# 遍历JSON反序列化树结构获取所有myentity节点及对应层级
C# 提取树形结构JSON中myentity及对应层级实现
现有反序列化类定义
你当前编写的两个C#类用于JSON反序列化,代码如下(建议补充public修饰符避免跨程序集反序列化失败):
public class structureTree { public structureChildren[] children { get; set; } } public class structureChildren { public structureChildren[] children { get; set; } public string myentity { get; set; } public bool sonGuide { get; set; } public string from { get; set; } public Int64 structureId { get; set; } public string to { get; set; } }
接口返回JSON结构示例
接口返回的是最外层为数组的嵌套树形结构,示例如下:
[ { "children": [ { "children": [ { "children": [ { "children": [], "myentity": "ENT2_A", "from": "2019-10-01", "structureId": 34353, "to": null }, { "children": [ { "children": [], "myentity": "ENT3_A", "from": "2019-10-01", "structureId": 34349, "to": null }, { "children": [], "myentity": "ENT3_B", "from": "2019-10-01", "structureId": 34351, "to": null } ], "myentity": "ENT2_B", "from": "2019-10-01", "structureId": 34348, "to": null } ], "myentity": "ENT1_A", "from": "2019-10-01", "structureId": 34348, "to": null } ], "myentity": "ENT0_A", "from": "2019-10-01", "structureId": 34348, "to": null } ] } ]
实现代码
针对获取所有myentity、同时记录所属层级/按层级分组的需求,直接用递归遍历嵌套节点即可,不需要修改原有实体类。
递归遍历方法
/// <summary> /// 递归遍历树形节点,按层级收集myentity /// </summary> /// <param name="currentNodes">当前待遍历的节点数组</param> /// <param name="currentLevel">当前节点所属层级,根下第一层可从0或1开始计数,按需调整</param> /// <param name="levelCollect">结果存储字典:key=层级,value=该层级下所有myentity集合</param> void TraverseNodes(structureChildren[] currentNodes, int currentLevel, Dictionary<int, List<string>> levelCollect) { if (currentNodes == null || currentNodes.Length == 0) return; // 初始化当前层级的存储容器 if (!levelCollect.ContainsKey(currentLevel)) { levelCollect[currentLevel] = new List<string>(); } foreach (var node in currentNodes) { // 收集当前节点的myentity if (!string.IsNullOrWhiteSpace(node.myentity)) { levelCollect[currentLevel].Add(node.myentity); } // 递归遍历子节点,层级+1 TraverseNodes(node.children, currentLevel + 1, levelCollect); } }
调用方式
// 1. 反序列化接口返回的JSON,注意最外层是数组结构 // 若使用System.Text.Json,把JsonConvert替换为JsonSerializer即可 var rootList = Newtonsoft.Json.JsonConvert.DeserializeObject<structureTree[]>(apiResponseJson); // 2. 初始化结果容器 var entityWithLevel = new Dictionary<int, List<string>>(); // 3. 启动遍历,根节点下的第一层子节点从层级0开始计数,要从1开始就把第二个参数改成1 foreach (var rootItem in rootList) { TraverseNodes(rootItem.children, 0, entityWithLevel); }
结果使用
- 若需要按层级分组提取myentity:直接使用返回的
entityWithLevel字典即可,字典的Key对应层级,Value对应该层级下的所有myentity列表。以上方示例JSON为例,返回结果为:- 层级0:[ENT0_A]
- 层级1:[ENT1_A]
- 层级2:[ENT2_A, ENT2_B]
- 层级3:[ENT3_A, ENT3_B]
- 若需要获取所有myentity+对应层级的扁平列表,遍历字典展开即可:
var flatResult = new List<(int Level, string EntityName)>(); foreach (var (level, entities) in entityWithLevel) { foreach (var entity in entities) { flatResult.Add((level, entity)); } }
注意:如果你的业务里层级计数规则不同,只需要调整调用递归方法时传入的初始层级值即可,不需要修改递归逻辑。
内容的提问来源于stack exchange,提问作者Franco
相关产品推荐
相关产品推荐

