首页 > 解决方案 > 建立目录结构

问题描述

我的情况是,我得到了一个代表目录结构的列表,格式如下:

"My Folder\Images"
"My Folder\Images\Gif"
"My Folder\Images\JPG"
"My Folder\Media"
"My Folder\Media\Mov"
"My Folder\Media\Mov\QT"
"My Folder\Media\MPG"

可以嵌套多少层没有限制。

我需要构建一些代表树视图的东西,格式如下:

public class Folder
{
    public string FolderName { get; set; }
    public List<Folder> Folders{ get; set; } // a list of subfolders
}

我只是无法获得构建这个非常正确的递归函数。大师的任何帮助将不胜感激。

TIA

编辑:我的完整班级定义是:

public class Folder
{
    public string Name { get; set; }

    public List<Folder> Folders { get; set; }
    public Folder(List<string> input)
    {
        foreach (var folder in input)
        {
            var delimPos = folder.IndexOf("\\");
            if (delimPos == -1)
            {
                Name = folder ;
            }
            else
            {
                Name = folder.Substring(0, delimPos);
                var subFolders= input.Select(o => o.Substring(delimPos + 1)).ToList();
                Folders= new List<Folder>();
                foreach (var subFolder in subFolders)
                {
                    Folders.Add(new Folder(new List<string>() { subFolder }));
                }

            }
        }
    }
}

标签: c#recursion

解决方案


你当然有这样的问题,分割处理后,分割处理的时候Images\Gif又要重新添加一个Images文件夹Images\JPG。第一个将有一个Gif子文件夹,第二个将有一个JPG子文件夹。

您可以通过对第一部分进行分组来解决此问题,并且只处理以下部分:

public static List<Folder> ParseInputRecursive(string[] input)
{
    var foldersInParts = input.Select(f => f.Split(new [] { '\\' }, StringSplitOptions.RemoveEmptyEntries).ToList()).ToList();

    return ParseInputRecursive(foldersInParts);
}

public static List<Folder> ParseInputRecursive(List<List<string>> input)
{
    var folders = new List<Folder>();

    foreach (var folderPartsGroup in input.GroupBy(p => p[0]))
    {
        var folder = new Folder { Name = folderPartsGroup.Key };

        // Remove parent name, skip parent itself
        var subFolders = folderPartsGroup.Select(f => f.Skip(1).ToList()).Where(f => f.Count > 0).ToList();

        folder.Folders = ParseInputRecursive(subFolders);

        folders.Add(folder);
    }

    return folders;
}

打印它们以验证:

// Sort to make sure parents always come first
Array.Sort(input);
var rootFolders = ParseInputRecursive(input);

foreach (var folder in rootFolders)
{
    PrintFoldersRecursive(folder);
}

public static void PrintFoldersRecursive(Folder folder, int depth = 0)
{
    Console.WriteLine(new string('*', depth++) + folder.Name);

    foreach (var subFolder in folder.Folders)
    {
        PrintFoldersRecursive(subFolder, depth);
    }
}

鉴于此输入:

var input = new string[] 
{
    @"F1\Images",
    @"F1\Images\Gif",
    @"F1\Images\JPG",
    @"F1\Media",
    @"F1\Media\Mov",
    @"F2\Docs",
    @"F2\Docs\Foo",
};

给出这个输出:

F1
*Images
**Gif
**JPG
*Media
**Mov
F2
*Docs
**Foo

推荐阅读