Gulzar
Gulzar

Reputation: 28014

C#: How to traverse all elements from a nested list, with variable nesting and variable type?

I want to create a function

void StringFromNestedList<T>(T theList);

theList could be of types such as

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

and so on.

Let's assume for each element, I want to activate a function all elements are assumed to have, such as ToString()

If I knew the amount of nesting, and size of each list, for example 2 levels of 4 elements each, I would do something like

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

But I don't know how many for loops are required.

Is it doable?

Upvotes: 0

Views: 856

Answers (2)

JonasH
JonasH

Reputation: 36541

An alternative iterative solution could be something like this:

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

The primary advantage would be that the objects are returned, and can be processed by something else. A downside is potential boxing, you could avoid this an additional check, but you will need to consider the behavior if lists contain dissimilar objects.

Upvotes: 0

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239754

I'm not sure trying to make it generic will gain you anything.

So, first assume that it'll just take an object.

void StringFromPossibleList(object theList)

Now, assume we don't want to deal with lists but with anything enumerable. Assume further that we've already got this function working - then for each item inside our enumerable, we can just call ourselves recursively!

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

By using recursion, we get as many levels of looping as it turns out we need.

Upvotes: 6

Related Questions