C#: 如何从一个嵌套列表中遍历所有元素,并使用变量嵌套和变量类型?

问题描述 投票:0回答:1

我想创建一个函数

void StringFromNestedList<T>(T theList);

TheList可以是这样的类型

List<List<List<List<double>>>>
List<List<int>>
List<List<List<SomeCustomType>>>

等等。

假设对于每个元素,我想激活一个所有元素都被假定为具有的功能,如 ToString()

如果我知道嵌套的数量,以及每个列表的大小,例如2个层次,每个层次有4个元素,我会做一些像这样的事情

for (var i = 0; i < 4; i++)
{
    for (var j = 0; j < 4; j++)
    {
        theList[i][j].ToString(); // yes, it doesnt really do anything
    }
}

但我不知道需要多少个for循环。

可以做吗?

c# generics multidimensional-array nested
1个回答
6
投票

我不知道想让它通用会有什么收获。

所以,首先假设它只是需要一个 object.

void StringFromPossibleList(object theList)

现在,假设我们不想处理列表,而是处理任何可枚举的东西。进一步假设我们已经有了这个函数--那么对于我们的可枚举里面的每一个项目,我们可以递归地调用自己的函数

{
    var enu = theList as IEnumerable;
    if(enu!=null)
    {
        foreach(var item in enu)
        {
            StringFromPossibleList(item);
        }
    }
    else
    {
        theList.ToString();
    }
}

通过使用递归,我们可以得到我们所需要的任意层次的循环。


0
投票

另一种迭代解决方案可以是这样的。

    public static IEnumerable<object> FlattenNestedLists(object obj)
    {
        var stack = new Stack();
        stack.Push(obj);
        while (stack.Count > 0)
        {
            var current = stack.Pop();
            if (current is IEnumerable list)
            {
                foreach (var item in list)
                {
                    stack.Push(item);
                }
            }
            else
            {
                yield return current;
            }
        }
    }

主要的好处是,对象被返回,可以被其他东西处理。缺点是潜在的框选,你可以通过一个额外的检查来避免这个问题,但是你需要考虑如果列表中包含不同对象时的行为。

© www.soinside.com 2019 - 2024. All rights reserved.