当前位置: 首页 > 知识库问答 >
问题:

递归方法C#的多个循环

长孙弘盛
2023-03-14

我有一个对象,里面有多个嵌套对象。类:

public class Element
{
    public string Key { get; set; }
    public List<Element> SubElement { get; set; }

    [XmlIgnore]
    public ElementConfig ElementConfig { get; set; }

    [XmlIgnore]
    public Element ParentElement { get; set; }

}
public class SubElement
{
    public string Key { get; set; }
    public List<Element> Elements { get; set; }
}

[Serializable]
public class ElementConfig {
    public string Key { get; set; }
    public string Label { get; set; }
    public string TypeName { get; set; }
    public string IconName { get; set; }
}

其基础是,一个元素可以有多个子元素以及它们自己的ElementConfig。我想为每个元素填充ElementConfig,如下所示:

    private void Recursion(Element element)
    {
        //TODO: use recursion ??
        foreach (Element item in element.SubElement)
        {
            item.ElementConfig = navigationStructureConfig.ElementConfigs.SingleOrDefault(x => x.Key == item.Key);
            item.ParentElement = element;

            foreach (Element x in item.SubElement)
            {
                x.ElementConfig = navigationStructureConfig.ElementConfigs.SingleOrDefault(e => e.Key == x.Key);
                x.ParentElement = item;

                foreach (Element y in x.SubElement)
                {
                    y.ElementConfig = navigationStructureConfig.ElementConfigs.SingleOrDefault(e => e.Key == y.Key);
                    y.ParentElement = x;
                }
            }                
        }
    }

这是起作用的,但我想用一个递归的方法来做这件事。这可能吗?

根据@johnathan Barclay的建议编辑我使用以下方法:

element.ElementConfig = navigationStructureConfig.ElementConfigs.SingleOrDefault(x => x.Key == element.Key);

        foreach (var item in element.SubElement)
        {
            item.ParentElement = element;
            Recursion(item); 
        }

这有助于获取每个第一个子元素ElementConfig。现在发生的情况是以下子元素没有填充。

共有2个答案

马权
2023-03-14

下面是一个通用的迭代解决方案:

public void PupulateConfigAndParent(Element element){
    foreach(var (item, parent) in DepthFirstWithParent(element, e => e.SubElement)){
        item.ElementConfig = navigationStructureConfig.ElementConfigs.SingleOrDefault(x => x.Key == item.Key);
        item.ParentElement = parent;
    }
}

    public static IEnumerable<(T Node, T Parent)> DepthFirstWithParent<T>(T self, Func<T, IEnumerable<T>> selector)
    {
        var stack = new Stack<(T Node, T Parent)>();
        stack.Push((self, self));
        while (stack.Count > 0)
        {
            var current = stack.Pop();
            yield return current;
            foreach (var child in selector(current.Node))
            {
                stack.Push((child, current.Node ));
            }
        }
    }

这样做的一个优点是可以对任何类型的树状结构重用泛型方法。注意,根节点将自己作为父节点。

侯博易
2023-03-14

假设还需要为根元素设置elementconfig:

private void Recursion(Element element)
{
    element.ElementConfig = navigationStructureConfig.ElementConfigs
        .SingleOrDefault(x => x.Key == element.Key);
    
    foreach (var item in element.SubElement)
    {
        item.ParentElement = element;    
        Recursion(item); // Recurse here
    }
}
 类似资料:
  • 假设我有n个list<T>的集合 比如 List<shool>、List<Det>、List<Student>..... for循环做法 foreacher(var item in List<shool>) { } 最终输出为字典 存储的是第一个为 拿这三个举例 shool_0 det_0 student_0 第二个为 shool 0 det 0 student 1 目前我的想法是递归 但是这边递

  • 我有一个递归算法,我用它来迭代分层数据结构,但不幸的是,对于一些数据,分层结构太深,以至于我得到了一个StackOverflow错误。我见过这种情况发生在大约150个节点的深度上,而数据可能会增长到更远的程度。对于上下文,这段代码将在有限的环境中运行,改变JVM堆栈大小不是一个选项,数据结构是给定的,代表不同的文件系统和目录和文件。 为了解决堆栈溢出问题,我尝试将算法转换为迭代算法。这不是我以前必

  • 本文向大家介绍C++实现递归函数的方法,包括了C++实现递归函数的方法的使用技巧和注意事项,需要的朋友参考一下 递归函数通俗来讲就是自己调用自己本身。这样有很大的好处,代码很方便简洁,把复杂的有规律的运算交给计算机去做。 1、首先定义问题。递归函数(recursion)需要设置一个函数,然后再可以循环往复的执行下去。 2、把问题换成公式。 如把阶乘之和定义为f(n)=n*f(n-1)。也就是说n*

  • 假设我们有以下数组,并且开始索引==0: 步骤0:索引=0,值=3 步骤1:索引=3,值=1 步骤5:索引=6,值=2 步骤6:索引=8,值=3 步骤7:索引=5,值=4

  • 我有两个非递归方法,其中一个读取字符串中的总“e”字符,另一个检查 ArrayList 是否按字母顺序排列。 递归方法的定义是方法调用自身。我相信我理解这个概念,但要实现它或将其转换为递归方法确实很困难。我怎样才能将这些方法转化为递归方法,同时我应该如何思考?此外,这是我的另一种方法,它只打印出指定数字大小的数字。 条件方法检查数字的第一个数字(从右起)是否大于第二个数字,并再次检查第二个是否大于

  • 我正在处理我当前的任务,即创建一个LinkedList数据结构,我已经创建了它以及其他方法,它工作得非常好。我正在处理我的最后一个问题,即制作一个toString方法。它应该: toString方法返回列表的字符串表示形式。用逗号分隔每个项目,并用大括号括住这些项目,例如{1,4,7,5}。公共toString方法必须调用私有递归方法来生成以逗号分隔的项目列表。(但您可以在公共方法中添加大括号。)