Search code examples
c#linqlistcollectionsdirectory-structure

Collect Directory and Sub Directories with mapping and index in a List<>


I want to collect the directory listing in a collection(a List<> perhaps) my directory structure is like :

MainFolder\ParentFolder1\SubFolder1    
                        \SubFolder2    
                        \SubFolder3

MainFolder\ParentFolder2\SubFolder1
                        \SubFolder2
                        \SubFolder3

I want to list all the subfolders mapped to their parent directories.

Also, the records will have index of ParentFolder 0-n in MainFolder and index of SubFolder 0-n in each ParentFolder.

I did tried below but not yet achieved

lstParents = (from f in Directory.GetDirectories(MainFolder)
             select  Data
         {
        parent =f
         }).ToList();

var lstSubDir = (from f in lstParents.Select(m => Directory.GetDirectories(m.parent).ToList());

Solution

  • You can use this overload of the GetDirectories method to find all subdirectories recursively:

    var mainDirectory = new DirectoryInfo(@"C:\temp\MainFolder");
    var subDirectories = mainDirectory.GetDirectories("*", SearchOption.AllDirectories);
    

    Then you can map them into pairs of directory/parent like this:

    var mappedDirectories = subDirectories.Select(sd => new { Parent=sd.Parent, Child=sd });
    

    If you want to exclude the first level of subdirectories (ParentFolder1 and ParentFolder2, in your case) you can filter them like this:

    var mappedDirectories = subDirectories
        .Where(sd => sd.Parent.FullName != mainDirectory.FullName)
        .Select(sd => new { Parent=sd.Parent, Child=sd });
    

    EDIT after you've asked for indices:

    You stated, that you'll always only have a nesting level of 2, the following piece of code will not work for deeper directory structures.

    var mainDirectory = new DirectoryInfo(@"C:\temp\MainFolder");
    var firstLevelDirectories = mainDirectory.GetDirectories().Select((f1,i) => new { 
      Parent = f1, 
      ParentIndex = i 
    });
    
    var secondLevelDirectories = firstLevelDirectories
      .SelectMany(f1 => f1.Parent.GetDirectories().Select((f2,i) => new {
        f1.Parent, 
        f1.ParentIndex, 
        Child = f2, 
        ChildIndex = i
    } ));
    

    This will give you a list of records, each containing

    • the parent directory,
    • the parent directory index,
    • the child directory and
    • the child directory index within its parent.