Pregunta

I am trying to make a File Directory browser in C# for a project.

I start with the current path (for this example it will be '/').

From the list of paths that I have

Example: /a/b, /a/bb, /a/bbb, /b/a, /b/aa, /b/aaa, /c/d, /d/e

I would like to return a list of distinct subdirectories

Expected return: /a/, /b/, /c/, /d/

How would one go about using LINQ to accomplish this?

¿Fue útil?

Solución

I think this just about covers it. Sample console app:

public static void Main()
{
    string[] paths = new[] { "/a/b", "/a/bb", "/a/bbb", "/b/a", "/b/aa", "/b/aaa", "/c/d", "/d/e" }; 
    string root = "/";

    Console.WriteLine(string.Join(", ", paths.Select(s => GetSubdirectory(root, s)).Where(s => s != null).Distinct()));
}

static string GetSubdirectory(string root, string path)
{
    string subDirectory = null;
    int index = path.IndexOf(root);

    Console.WriteLine(index);
    if (root != path && index == 0)
    {
        subDirectory = path.Substring(root.Length, path.Length - root.Length).Trim('/').Split('/')[0];
    }

    return subDirectory;
}

See fiddle: http://dotnetfiddle.net/SXAqxY

Sample input: "/"
Sample output: a, b, c, d

Sample input: "/a"
Sample output: b, bb, bbb

Otros consejos

I may missing the point, but wouldn't something like this be what you are looking for?

var startingPath = @"c:\";

var directoryInfo = new DirectoryInfo(startingPath);

var result = directoryInfo.GetDirectories().Select(x => x.FullName).ToArray();

The result would be an array of paths to the various immediate sub directories (example):

  1. "c:\Boot"
  2. "c:\Temp"
  3. etc.
void Main()
{
  string [] paths = {  @"/a/b", @"/a/bb", @"/a/bbb", @"/b/a", @"/b/aa", @"/b/aaa", @"/c/d", @"/d/e" };

  var result = paths.Select(x => x.Split('/')[1]).Distinct();

  result.Dump();
}

If you don't know if you have a leading / then use this:

var result = paths.Select(x =>x.Split(new string [] {"/"},
                                        StringSplitOptions.RemoveEmptyEntries)[0])
                  .Distinct();

You can use Path.GetPathRoot

var rootList = new List <string>();

foreach (var fullPath in myPaths)
{
    rootList.Add(Path.GetPathRoot(fullPath))
}

return rootList.Distinct();

Or:

myPaths.Select(x => Path.GetPathRoot(x)).Distinct();

Or use Directory.GetDirectoryRoot:

myPaths.Select(x => Directory.GetDirectoryRoot(x)).Distinct();

Edit

If you want the N+1 path you could do:

string dir = @"C:\Level1\Level2;  

string root = Path.GetPathRoot(dir);

string pathWithoutRoot = dir.Substring(root.Length);       

string firstDir = pathWithoutRoot.Split(Path.DirectorySeparatorChar).First();

Assuming you have a list of paths named paths, you can do something like this:

string currentDirectory = "/";
var distinctDirectories = paths.Where(p => p.StartsWith(currentDirectory)
                               .Select(p => GetFirstSubDir(p, currentDirectory)).Distinct();


...


string GetFirstSubDir(string path, string currentDirectory)
{
    int index = path.IndexOf('/', currentDirectory.Length);
    if (index >= 0)
        return path.SubString(currentDirectory.Length - 1, index + 1 - currentDirectory.Length);
    return path.SubString(currentDirectory.Length - 1);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top