Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在列表中查找嵌套级别<&燃气轮机;使用属性_C#_Foreach_Nested - Fatal编程技术网

C# 在列表中查找嵌套级别<&燃气轮机;使用属性

C# 在列表中查找嵌套级别<&燃气轮机;使用属性,c#,foreach,nested,C#,Foreach,Nested,我试图用从服务接收到的一些数据构建一个树结构。不幸的是,我无法控制所接收数据的结构。对象的构建方式如下所示: class Module { public string ModuleCode {get;set;} public string ParentCode {get;set;} } 基本上,我得到了大约200个这样的对象的列表,我需要找到一种方法来对它们进行排序和排列,这样孩子们才能正确地与他们的父母联系起来 我现在有一个工作方法,就是使用foreach循环,但是它很

我试图用从服务接收到的一些数据构建一个树结构。不幸的是,我无法控制所接收数据的结构。对象的构建方式如下所示:

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
            }
      }
}
foreach(moduleList.Where(x=>string.IsNullOrWhiteSpace(x.ParentCode))中的var模块)
{
//模块级别1--此处仅限最上面的父模块
moduleLevel=1;
_highestModuleLevel=_highestModuleLevelx.ParentCode==module.ModuleCode)中的变量module2)
{
//模块级别2——第一个子模块
moduleLevel=2;
_highestModuleLevel=_highestModuleLevelx.ParentCode==module1.ModuleCode)中的变量module2)
{
//模块级——第二级模块的子级
moduleLevel=3;
_highestModuleLevel=_highestModuleLevel
}


正如我所说,这个解决方案确实有效,但我真的觉得必须有一种更具程序性、更干净、更高效的方法来处理这个问题

下面假设您有一个方法,可以返回一个扁平的
模块列表
。此外,这是未经测试-可能是打字错误或错误。。。就在这里,我将开始为您提供一个
模块的分层列表
。请注意,我在您的
模块
类中添加了
父类
子类

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);
        }
    }
}

首先,我会将
列表
转换为
列表

然后我将用一些
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();

在你的树的根上是什么?@DavidG,在根上,我按ParentCode为null的模块(x=>string.IsNullOrWhiteSpace(x.ParentCode))进行过滤,目标是什么?我看不出你把物品放在树上的什么地方…@RenéVogt,最终目标是用这些未分类的物品制作菜单。我需要为每个模块创建一个父/子关系,这样我就可以构建菜单,我没有为了简洁而显示它,但实际上我正在使用Razor为每个级别编写html。如果说得更清楚的话,我也可以把它包括在内,我只是觉得没必要,你有没有试过递归地做这个?这将解决n个嵌套对象的问题。顺便使用冲突的
m
lambda变量,然后使用它们比较
m.ParentCode==m.ModuleCode
@MobigItal谢谢,修复了它。这就是我在离开办公室前匆匆忙忙地从头顶写东西时所发生的情况……同样不幸的是,这种结构没有利用
模块中的
字典
。其中(…)
区域,如果有很多模块,可能会变得非常慢。只是说说而已。另一个解决方案是,模块查找其父级并将其作为子级添加,这样效果更好—包括优化。我唯一的保留是,您正在合并原始
模块
类和新的
树节点类
类的目的。如果您有一个单独的
TreeNode
类,那么对于请求者来说它会更干净。你永远不知道他们的输入类的起源是什么,他们可能不想从中派生,等等@Mobigital-true-很容易补救。我只是想给OP一个简单的起点。感谢您完成了从孩子到家长的查找,并在树重建中使用了字典@Mobigital-只是注意那个大O:)
List<Module> modules = moduleList.Cast<Module>();
Dictionary<string, Module> codeToModule = modules.ToDictionary(m => m.ModuleCode, m => m);
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));