列出分层结构路径的<string>

时间:2016-01-22 13:15:36

标签: c#

我有一个像这样的路径列表:

Root 
Root/Folder1 
Root/Folder1/SubFolder1.1 
Root/Folder1/SubFolder1.2
Root/Folder2 
OtherRootFolder 
OtherRootFolder/Folder1

我需要使用Folder + List of Children

创建一个层次结构
public class FolderTreeModel
{
    public string Title { get; set; }
    public List<FolderTreeModel> Children { get; set; }
}

如何将这些路径拆分为该结构,以便看起来像:

Root
'-- Folder1
'---- SubFolder1.1
'---- SubFolder1.2
'-- Folder2
'-- OtherRootFolder
'---- Folder1

提前致谢。

1 个答案:

答案 0 :(得分:4)

这是您需要的代码:

Action<FolderTreeModel, IEnumerable<string>> ensureExists = null;
ensureExists = (ftm, ts) =>
{
    if (ts.Any())
    {
        var title = ts.First();
        var child = ftm.Children.Where(x => x.Title == title).SingleOrDefault();
        if (child == null)
        {
            child = new FolderTreeModel()
            {
                Title = title,
                Children = new List<FolderTreeModel>(),
            };
            ftm.Children.Add(child);
        }
        ensureExists(child, ts.Skip(1));
    }
};

然后我可以这样做:

var paths = new []
{
    "Root",
    "Root/Folder1",
    "Root/Folder1/SubFolder1.1",
    "Root/Folder1/SubFolder1.2",
    "Root/Folder2",
    "OtherRootFolder",
    "OtherRootFolder/Folder1",
};

var root = new FolderTreeModel() { Title = "/", Children = new List<FolderTreeModel>() };

foreach (var path in paths)
{
    var parts = path.Split('/');
    ensureExists(root, parts);
}

然后我得到了这个结果:

result

如果您将FolderTreeModel的定义更改为:

public class FolderTreeModel : List<FolderTreeModel>
{
    public string Title { get; set; }
}

...然后代码变得更简单:

Action<FolderTreeModel, IEnumerable<string>> ensureExists = null;
ensureExists = (ftm, ts) =>
{
    if (ts.Any())
    {
        var title = ts.First();
        var child = ftm.Where(x => x.Title == title).SingleOrDefault();
        if (child == null)
        {
            child = new FolderTreeModel() { Title = title };
            ftm.Add(child);
        }
        ensureExists(child, ts.Skip(1));
    }
};

var root = new FolderTreeModel() { Title = "/" };

其余代码是相同的。