如何从表示C#或VB中的目录结构的字符串列表创建集合 [英] how to create a collection from list of strings that represents a directory structure in C# or VB

查看:102
本文介绍了如何从表示C#或VB中的目录结构的字符串列表创建集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我检查了这篇文章,但它是在Python,第一和第二

First, I did check this post but it is in Python, first, and second it appears to be actually making the directories, which I cannot do in this scenario.

其次,这些目录不是存在的,我也不能创建它们。

Second, these are not directories that exist, nor can I create them.

我在C#中有一个输入,如下所示:

I have an input in C# like this:

        List<string> filePaths = new List<string>();
        filePaths.Add(@"ProgramDir\InstallDir\Module1\mod1pack1.exe");
        filePaths.Add(@"ProgramDir\InstallDir\Module1\mod1pack2.exe");
        filePaths.Add(@"ProgramDir\InstallDir\Module2\mod2pack1.exe");
        filePaths.Add(@"ProgramDir\InstallDir\Module1\SubModule1\report1.rpt");
        filePaths.Add(@"SystemDir\DependencyDir\dependency1.dll");
        filePaths.Add(@"SystemDir\DependencyDir\dependency2.dll");

我一直在尝试创建一个表示这个结构的对象,可视化如下:

What I have been trying to do is create an object that represents this structure, such that it could be visualized like this:

-ProgramDir
    Installdir
        Module1
            mod1pack1.exe
            mod1pack2.exe
            -SubModule1
                 report1.rpt
        Module2
            mod2pack1.exe
-SystemDir
    -DependencyDir
         dependency1.dll
     dependency2.dll

我试过的是以下的各种版本,一些帮助找出我错了的地方。

What I have tried is various versions of the following, and I could really use some help to figure out where I've got it wrong.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SetFilePathList();
            DTree forest = new DTree();
            List<DTreeBranch> branches = new List<DTreeBranch>();
            foreach (string path in filePaths)
            {
                forest.GrowTree(path.Split('\\'), branches);
            }
            forest.SubBranches.AddRange(branches);
        }
        private static List<string> filePaths { get; set; }
        private static void SetFilePathList()
        {
            filePaths = new List<string>();
            filePaths.Add(@"ProgramDir\InstallDir\Module1\mod1pack1.exe");
            filePaths.Add(@"ProgramDir\InstallDir\Module1\mod1pack2.exe");
            filePaths.Add(@"ProgramDir\InstallDir\Module2\mod2pack1.exe");
            filePaths.Add(@"ProgramDir\InstallDir\Module1\SubModule1\report1.rpt");
            filePaths.Add(@"SystemDir\DependencyDir\dependency1.dll");
            filePaths.Add(@"SystemDir\DependencyDir\dependency2.dll");
        }
    }
    public class DTree
    {
        public List<DTreeBranch> SubBranches { get; set; }
        public string BranchName { get; set; }
        public DTree() { SubBranches = new List<DTreeBranch>(); }
        public DTreeBranch AddChildren(string[] childElements, DTreeBranch branch)
        {
            DTreeBranch childBranch;
            foreach (string element in childElements)
            {
                childBranch = new DTreeBranch();
                childBranch.BranchName = element;
                branch.SubBranches.Add(childBranch);
                var query = from q in childElements
                            where q != childBranch.BranchName
                            select q;
                AddChildren(query.ToArray<string>(), childBranch);
            }
            return branch;
        }
        public void GrowTree(string[] pathElements, List<DTreeBranch> Branches)
        {
            DTreeBranch result = Branches.Find(delegate(DTreeBranch b)
            {
                return b.BranchName == pathElements[0];
            });

            if (result == null)
            {
                DTreeBranch newRootBranch = new DTreeBranch();
                newRootBranch.BranchName = pathElements[0];
                Branches.Add(newRootBranch);
                GrowTree(pathElements, Branches);
            }
            else
            {
                var query = from q in pathElements
                            where q != result.BranchName
                            select q;
                DTreeBranch childBranch = AddChildren(query.ToArray<string>(), result);
                Branches.Add(childBranch);
            }
        }
    }
    public class DTreeBranch
    {
        public List<DTreeBranch> SubBranches { get; set; }
        public string BranchName { get; set; }
        public DTreeBranch()
        {
            SubBranches = new List<DTreeBranch>();
        }
    }
}

主要的是输出只有两层深。我想我的意思是,新的元素被添加到深度,而不是广度,我有点失去了如何有效地通过这一点。我还认为我有更多的代码比我需要。

The main thing is that the output is only two layers deep. I guess what I'm saying is that the new elements are added to the depth, not the breadth, and I'm at a loss as to how to effectively work through this. I also think that I have way more code than I need.

提前感谢。

推荐答案

我不知道我们的目标是什么,但简单的递归解析将会很容易。写这个,希望它有帮助。你可以使它显着更喜欢,如果你想,与DTrees和子分支,或单独的集合文件和目录,等等。我真的不明白这里的代码是什么。如果它与WIX有关,对不起;)你可以总是使用这样的东西解析到树中,然后将其转换为不同的格式。

I'm not sure exactly what our goals are, but a simple recursive parse will do it quite easily. Wrote this up, and hope it helps. You can make it significantly more fancy if you want, with DTrees and sub branches, or separate collections for Files and Directories, etc. I don't really understand what all that code in there is for. If it has something to do with WIX, I'm sorry ;) And you could always use something like this to parse it out into the tree, and then convert that sanely to a different format.


  • 这假设没有重复的叶节点(文件名)。


主节点类 -

public class Node
{
    public string Name { get; set; }
    public bool IsDirectory { get; set; }
    public List<Node> Children = new List<Node>();

    internal void AddChildren(string f)
    {
        var dirs = Path.GetDirectoryName(f);
        if (string.IsNullOrEmpty(dirs))
        {
            // we are adding a file
            var file = Path.GetFileName(f);
            Children.Add(new Node {Name = file, IsDirectory = false});
        }
        else
        {
            // we are adding a directory
            var firstDir = dirs.Split(Path.DirectorySeparatorChar)[0];
            var childNode = Children.FirstOrDefault(d => d.Name == firstDir);
            if (childNode == null)
            {
                childNode = new Node {Name = firstDir, IsDirectory = true};
                Children.Add(childNode);
            }

            var subPath = f.Substring(firstDir.Length + 1);
            childNode.AddChildren(subPath);
        }
    }
}

调用很简单, this:

Calling it is simple, like this:

var filePaths = new List<string> { 
    @"ProgramDir\InstallDir\Module1\mod1pack1.exe",
    @"ProgramDir\InstallDir\Module1\mod1pack2.exe",
    @"ProgramDir\InstallDir\Module2\mod2pack1.exe",
    @"ProgramDir\InstallDir\Module1\SubModule1\report1.rpt",
    @"SystemDir\DependencyDir\dependency1.dll",
    @"SystemDir\DependencyDir\dependency2.dll",
};

var node = new Node { Name = "Root", IsDirectory = true };
foreach (var f in filePaths )
{
    node.AddChildren(f);
}

打印(每级有缩进,给我这个)

Printing it out (with indent per level, gives me this)

public static void PrintNode(Node node, int indent)
{
    if (indent > 0) // don't print out root directory (level 1). 
    {
        var ending = node.IsDirectory ? Path.DirectorySeparatorChar.ToString() : "*";
        Console.WriteLine("{0}{1}{2}", new string('\t', indent - 1), node.Name, ending);
    }
    node.Children.ForEach(n => PrintNode(n, indent + 1));
}

ProgramDir\
    InstallDir\
            Module1\
                    mod1pack1.exe*
                    mod1pack2.exe*
                    SubModule1\
                            report1.rpt*
            Module2\
                    mod2pack1.exe*
SystemDir\
    DependencyDir\
            dependency1.dll*
            dependency2.dll*

这篇关于如何从表示C#或VB中的目录结构的字符串列表创建集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆