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