Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Linq to flatten a nested list instead of a foreach loop

Tags:

c#

asp.net

linq

I have a recurring class - I've simplified it below.

public class SiloNode
{
    public string Key { get; private set; }
    public string Url { get; private set; }
    public List<SiloNode> Children { get; private set; }
}

Although, in theory, it could nest forever, the nodes will only ever go down two levels. So, a top-level node can have a child, but a child can't have a child.

I have a master list containing all of the top level nodes with their nested child nodes.

However, I need to get all nodes into a single flat list - node 1, followed by its children, followed by node 2 etc.

My knowledge in this area is limited, but I could do something like a foreach over the master list and create a new list, like this:

public IEnumerable<SiloNode> GetLinks(IEnumerable<SiloNode> masterList)
{
    var newList = new List<SiloNode>();

    foreach (var node in masterList)
    {
        newList.Add(node);
        newList.AddRange(node.Children);
    }

    return newList;
}

However, I know there's probably a much better way available but I just can't work out how to convert the foreach into a Linq statement that will do the same thing. In other words, select the parent and its children together.

Any help appreciated.

like image 579
John Ohara Avatar asked Dec 23 '22 04:12

John Ohara


1 Answers

You can use SelectMany, just concat the single parent and it's children:

List<SiloNode> newList = masterList.SelectMany(n => new[]{ n }.Concat(n.Children)).ToList();
like image 94
Tim Schmelter Avatar answered Mar 03 '23 14:03

Tim Schmelter