如何从任意层级嵌套的反序列化JSON对象提取ChildComponent列表?
提取所有嵌套层级的ChildComponent到单一列表
要解决这种无限嵌套的组件提取问题,递归遍历是最可靠的方案——文件夹和组件本身都支持多层嵌套,递归能确保遍历到每一层的内容,不会遗漏任何组件。
步骤1:编写递归方法处理文件夹
这个方法会先提取当前文件夹下的所有组件,再递归处理该文件夹的子文件夹,逐层深入:
private void ProcessFolder(ChildFolder folder, Dictionary<int, ComponentModel> componentDict) { // 处理当前文件夹下的直接组件 if (folder.childComponents != null && folder.childComponents.Count > 0) { foreach (var component in folder.childComponents) { // 转换为目标Model并加入字典 Enum.TryParse<ComponentState>(component.state, out var state); Enum.TryParse<ComponentType>(component.type, out var type); var model = new ComponentModel { Id = component.id, Name = component.name, UUID = component.uuid, State = state, Type = type }; componentDict.TryAdd(model.Id, model); // 别忘了处理组件自身嵌套的子组件 ProcessComponent(component, componentDict); } } // 递归处理下一级文件夹 if (folder.childFolders != null && folder.childFolders.Count > 0) { foreach (var subFolder in folder.childFolders) { ProcessFolder(subFolder, componentDict); } } }
步骤2:编写递归方法处理组件的子组件
因为ChildComponent自身也包含childComponents列表,需要单独递归处理这部分嵌套内容:
private void ProcessComponent(ChildComponent component, Dictionary<int, ComponentModel> componentDict) { if (component.childComponents != null && component.childComponents.Count > 0) { foreach (var subComponent in component.childComponents) { // 转换为目标Model并加入字典 Enum.TryParse<ComponentState>(subComponent.state, out var state); Enum.TryParse<ComponentType>(subComponent.type, out var type); var model = new ComponentModel { Id = subComponent.id, Name = subComponent.name, UUID = subComponent.uuid, State = state, Type = type }; componentDict.TryAdd(model.Id, model); // 递归处理当前子组件的下一级子组件 ProcessComponent(subComponent, componentDict); } } }
步骤3:整合调用覆盖所有层级
替换你原来的循环逻辑,调用上述递归方法即可覆盖所有嵌套层级:
var dictComponents = new Dictionary<int, ComponentModel>(); // 处理根目录下的所有子文件夹 if (js.data.childFolders != null && js.data.childFolders.Count > 0) { foreach (var rootFolder in js.data.childFolders) { ProcessFolder(rootFolder, dictComponents); } } // 处理根目录下的直接组件(注意Data的childComponents是List<object>,需要转换类型) if (js.data.childComponents != null && js.data.childComponents.Count > 0) { foreach (var obj in js.data.childComponents) { if (obj is ChildComponent rootComponent) { // 转换并加入字典 Enum.TryParse<ComponentState>(rootComponent.state, out var state); Enum.TryParse<ComponentType>(rootComponent.type, out var type); var model = new ComponentModel { Id = rootComponent.id, Name = rootComponent.name, UUID = rootComponent.uuid, State = state, Type = type }; dictComponents.TryAdd(model.Id, model); // 处理根组件的嵌套子组件 ProcessComponent(rootComponent, dictComponents); } } } // 若需要列表而非字典,直接转换即可 var allComponents = dictComponents.Values.ToList();
原代码的问题说明
你之前的while循环只遍历了第一层文件夹,没有深入处理每个文件夹下的childFolders,导致所有嵌套在子文件夹里的组件都被遗漏。递归方法会逐层深入遍历所有层级,确保没有任何组件被漏掉。
内容的提问来源于stack exchange,提问作者Talcon
相关产品推荐
相关产品推荐

