嵌套 foreach 依赖于前一个 foreach 的变量

Nested foreach that depends on variable of the previous foreach

提问人:ng80092b 提问时间:8/13/2023 更新时间:8/13/2023 访问量:52

问:

我已经写了一段代码,可以正确地循环低谷列表并完成我需要的工作,但我认为我的做法有点愚蠢,我正在寻找一种方法来有效地编写它,有一段时间,或重复循环。

这是有效的方法:

            data = List<string>; //a new list of strings
            foreach (var string in data) 
            {
                data = createNewList(string); //for every string inside the previous, a new list is created
                foreach (var string2 in data) 
                {
                     data = createNewList(string2); //for every string in the last one, a new list is created
                    foreach (var string3 in data)
                    {
                         data = createNewList(string3);
                        foreach (var string4 in data)
                        {
                                //And so on...
                        }
                    }
                }
            }

我尝试的(使用真实代码)在第一次迭代后停止而没有错误......但我希望它成为无限的,只要有一个子列表正在制作

            dataSingles = addFolderItemsList(sourcelist);
            foreach (NodeN node in dataSingles)
            {
               

                while (flag > 0)
                {
                    flag = 0;
                    foreach (NodeN subnode in dataSingles)
                    {
                        dataSingles = addFolderItemsList(subnode.ChildrenN);
                        if (dataSingles.Count() > 0) { flag = 1; }
                      
                    }
                   
                   
            }
C# 列表 while-loop foreach 迭代

评论

1赞 Zohar Peled 8/13/2023
似乎您正在寻找递归。但要注意:如果递归代码太深,递归代码可能会抛出一个。StackOverflowException
0赞 ng80092b 8/13/2023
事实上,这是我想做的递归。如果我不小心犯了这个错误,我会在这个论坛上获得某种奖牌吗?

答:

1赞 Alok Marathe 8/13/2023 #1

因此,基本上您正在尝试执行一个嵌套循环,该循环遍历字符串(或元素)列表,并基于上一个列表中的元素创建新列表。嵌套 foreach 循环的初始方法不适合此方案,因为要修改循环中的相同数据变量,这可能会导致意外行为。

根据您的描述,您似乎希望继续创建新的项目列表,直到不再生成子列表。您已经尝试使用 while 循环来实现此目的,但实现有点偏离。

下面介绍如何使用 while 循环更有效地构建代码以实现所需的行为:

List<NodeN> dataSingles = addFolderItemsList(sourcelist);
int flag = 1; // Initialize flag to 1 to start the loop

while (flag > 0)
{
    flag = 0; // Reset the flag at the beginning of each iteration

    List<NodeN> newDataSingles = new List<NodeN>(); // Create a new list for the next level

    foreach (NodeN subnode in dataSingles)
    {
        List<NodeN> subnodeChildren = addFolderItemsList(subnode.ChildrenN);
        
        if (subnodeChildren.Count() > 0)
        {
            flag = 1; // Set the flag to 1 if there are sublists being generated
            newDataSingles.AddRange(subnodeChildren); // Add the sublists to the new list
        }
    }

    dataSingles = newDataSingles; // Update the list with the new sublists for the next iteration
}

在此代码中,我们维护两个列表:dataSingles(保存当前级别的节点)和 newDataSingles(保存下一级节点)。 只要生成子列表(标志大于 0),while 循环就会继续。在每次迭代中,我们遍历当前级别的节点,生成子列表,并更新 newDataSingles 列表。最后,我们用新的子列表更新 dataSingles 列表,以便进行下一次更新。

此方法可确保不会修改要迭代的同一列表,并且只要生成新的子列表,它就应该允许你有效地循环访问列表的层次结构。

1赞 QueryKiller 8/13/2023 #2

只需使用递归 ProcessList 函数即可遍历列表。

void ProcessList(List<string> data)
{
    List<string> newData = new List<string>();
    foreach (var item in data)
    {
        newData.AddRange(createNewList(item));
    }

    if (newData.Count > 0)
    {
        ProcessList(newData);
    }
}

ProcessList(data); 

如果你想使用while循环,请使用我下面的代码片段,递归将是这个解决方案的最佳方法,所以请记住这一点

List<string> currentData = data; 
while(currentData.Count > 0) 
{
    List<string> newData = new List<string>();
    foreach(var item in currentData) 
    {
        newData.AddRange(createNewList(item));
    }
    currentData = newData;
}