2

I'm fairly new to C# and I'm attempting to take the tree structure I've created from a list, and write that to the file system. (I've used this answer).

That is, I want to create the directories and subdirectories in the proper depth. However, I'm getting stuck on depth and cannot think of how to loop through each iteration of the depth, then back out to start writing again, without just writing all the 0-depth directories, then all the 1-depth directories, etc., in the same location.

I'm thinking there's another recursive routine/method/function, but I just can't wrap my head around it. I'd like to get to the next level (ha) in my understanding of programming.

static void Test(IEnumerable<TreeItem<category>> categories, int deep = 0)
{
    foreach (var c in categories)
    {
        for (int i = 0; i < deep; ++i) {
            System.IO.Directory.CreateDirectory(c.Item.Name); 
    }
        Test(c.Children, deep + 1);
    }
}
Community
  • 1
  • 1
sqldoug
  • 429
  • 1
  • 3
  • 10

1 Answers1

4

Because Directory.CreateDirectory creates all the parent directories for you, assuming you have the full path stored for each node, you only need to pass leaf nodes (nodes with no children) to it.

You can write a recursive search to retrieve leaf nodes, then pass that list to CreateDirectory.

static IEnumerable<TreeItem<category>> GetLeafs(IEnumerable<TreeItem<category>> tree) 
{
    foreach (var item in tree)
    {
        if (item.Children.Any()) 
        {
            // this is not a leaf, so find the leaves in its descendants
            foreach (var leaf in GetLeafs(item.Children))
                yield return leaf;                
        }
        else
        {
            // no children, so this is a leaf
            yield item;                
        }
    }
}

static void CreateDirectories(IEnumerable<TreeItem<category>> categories)
{
    foreach (var leaf in GetLeafs(categories)) 
    {
        System.IO.Directory.CreateDirectory(leaf.Item.Name);
    }
}

If you don't have the full path against each node, then you can use the same structure as GetLeafs (although it turns out much simpler, because you don't need to return anything back up the call-chain) to recursively walk the tree, creating directories as you go deeper:

static void CreateDirectories(IEnumerable<TreeItem<category>> tree) 
{
    foreach (var item in tree)
    {
        Directory.Create(c.Item.Name);        
        CreateDirectories(item.Children);                        
    }
}

This method is simpler, but will result in more calls to Directory.Create, which could conceivably have a performance impact.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • That's interesting, thank you for the examples. I hadn't realized one could write `var leaf in GetLeafs(categories)` -- that is, `in` the result of a call. – sqldoug Aug 21 '15 at 06:17