我尝试使用我从服务中接收的一些数据来构建树结构。不幸的是,我无法控制我收到的数据结构。该对象是这样构建的:
class Module
{
public string ModuleCode {get;set;}
public string ParentCode {get;set;}
}
基本上,我得到了大约200个这些对象的列表,我需要找到一种方法对它们进行排序并安排它们,以便孩子们与父母正确联系。
我现在有一个使用foreach循环的工作方法,但它很难看,并且仅限于我硬编码的foreach循环的数量。我想要一些更有活力的东西。
foreach (var module in moduleList.Where(x => string.IsNullOrWhiteSpace(x.ParentCode)))
{
//Module Level 1 -- Only uppermost parent modules here
moduleLevel = 1;
_highestModuleLevel = _highestModuleLevel < moduleLevel ? moduleLevel : _highestModuleLevel;
foreach (var module2 in moduleList.Where(x => x.ParentCode == module.ModuleCode))
{
//Module Level 2 -- 1st children modules
moduleLevel = 2;
_highestModuleLevel = _highestModuleLevel < moduleLevel ? moduleLevel : _highestModuleLevel;
foreach (var module2 in moduleList.Where(x => x.ParentCode == module1.ModuleCode))
{
//Module Level -- children of the 2nd level modules
moduleLevel = 3;
_highestModuleLevel = _highestModuleLevel < moduleLevel ? moduleLevel : _highestModuleLevel;
//Goes on for however many foreaches I can nest
}
}
}
}
就像我说的,这个解决方案确实有效,但我真的觉得必须有一个更程序化,更清晰,更有效的方法来处理这个问题
答案 0 :(得分:2)
从
开始以下假设您有一个方法可以返回Modules
的扁平列表。此外,这是未经测试的 - 可能是拼写错误或错误...大约在我开始为您提供Modules
的分层列表的地方。请注意,我已将Parent
和Children
添加到您的Module
课程中。
class Module
{
public Module()
{
this.Children = new List<Module>();
}
public string ModuleCode {get; set;}
public string ParentCode {get; set;}
public Module Parent {get; set;}
public List<Module> Children {get; private set;}
}
static void main()
{
List<Module> moduleList = GetFlattenedModules();
IDictionary<string, Module> moduleCodeToModule =
moduleList.ToDictionary(m => m.ModuleCode);
foreach (Module module in moduleList)
{
if (module.ParentCode != null)
{
module.Parent = moduleCodeToModule[module.ParentCode];
module.Parent.Children.Add(module);
}
}
}
你得到什么
这会让您获得原始列表,但每个Module
可能有孩子,并且可能有父母。
你可能想要什么
您可能真正想要的只是顶级Modules
的列表,并且您对该事物进行了数据绑定。这很简单,例如:
List<Module> topLevelModules = moduleList.Where(m => m.Parent == null).ToList();
答案 1 :(得分:0)
首先,我会将List<object>
投射到List<Module>
:
List<Module> modules = moduleList.Cast<Module>();
然后我会创建一个字典,以便通过ModuleCode
Dictionary<string, Module> codeToModule = modules.ToDictionary(m => m.ModuleCode, m => m);
然后我会用一些TreeNode
个对象创建一个树:
public class TreeNode
{
public Module Module { get; set; }
public Module Parent { get; set; }
public List<Module> Children { get; set; }
}
List<TreeNode> flatNodes = modules.Select(m => new TreeNode
{
Module = m,
Parent = m.ParentCode == null ? null : codeToModule[m.ParentCode],
Children = modules.Where(cm => cm.ParentCode == m.ModuleCode).ToList();
}).ToList();
现在你有一个所有树节点的平面列表,每个节点都引用它的父节点(如果有的话)并且有一个子节点列表。
您现在可以选择根节点:
List<TreeNode> rootNodes = flatNodes.Where(node => node.Parent == null).ToList();
你说你需要筑巢深度。您现在可以递归计算:
public int GetDepth(TreeNode current, int depth)
{
return current.Children.Max(child => GetDepth(child, depth + 1));
}
int depth = rootNodes.Max(node => GetDepth(node, 0));