tags:

views:

135

answers:

3

Say I have this list

List<string> sampleList = new List<string>
{
   "C:\\Folder1",
   "D:\\Folder2",
   "C:\\Folder1\\Folder3",
   "C:\\Folder111\\Folder4"
};

I'd like to remove the paths that are contained in other folders, for example we have C:\Folder1 and C:\Folder1\Folder3

the list's third entry should go away because C:\Folder1 contains C:\Folder1\Folder3

is there something that does that in the .net framework or do i have to write the algo myself?

A: 

You should do yourself. Do you think that .net implemented a method to do such a specific task? Use string methods.

erasmus
probably not, but I was expecting there would be a method like Path1.isIn(Path2) - like "C:\Folder1\Folder3".isIn("C:\Folder1") => true
andrew
no there is no such method. because path is just a string, use string methods like StartsWith (as @Stefan said)
erasmus
Actually, a path is more than a string. Consider mount points. D:\ could be the same path as C:\SecondDisk\
MSalters
+2  A: 

Assuming it is not a huge list.

List<string> sampleList = new List<string>
{
   "C:\\Folder1",
   "D:\\Folder2",
   "C:\\Folder1\\Folder3",
   "C:\\Folder111\\Folder4",
   "C:\\Folder1"
};

string sep = Path.DirectorySeparatorChar.ToString();
List<string> shortList = sampleList.Where (l => 
    sampleList.Where(s => 
        l.StartsWith(s + (s.EndsWith(sep) ? String.Empty : sep)) && s != l).Count() == 0
).Distinct().ToList();
Don
You're doing quite some work depending on `s.EndsWith(sep)`, effectively in a loop. It's probably cleaner and easier to normalize inputs beforehand.
MSalters
I realize there are ways to make it more effective thus the "Assuming it is not a huge list."
Don
+3  A: 

I most probably would use string operations on normalized paths strings:

path1 = Path.GetFullPath(path1);
path2 = Path.GetFullPath(path2);

// depending on os, ignore casing, eg by converting to lowercase

if (path1.StartsWith(path2)) 
{
  // ...
}

full example:

var normalizedPaths = sampleList
    .Select(x => Path.GetFullPath(x).ToLowerCase())
    .ToList();

var reducedList = normalizedPaths
    .Distinct()
    .Where(x => !normalizedPaths.Contains(
        y => y.StartsWith(x + Path.DirectorySeparatorChar)
        && x != y));
Stefan Steinegger
You need to ensure that GetFullPath is terminated with a backslash, otherwise `C:\\Folder1` will "mask" `C:\\Folder11`
peterchen
Agree about `Path.GetFullPath` depending on the source of the strings in the first place but `ToLower()` would mess up on Linux, mono or samba shares(?), that doesn't prevent directories with difference in casing I'd think.
Don
@Don, yes, that's my commend "depending on os ...". I don't know if you can find out if paths are case sensitive or not, this code is just an example.
Stefan Steinegger
@peterchen, I already fixed it. it is the PathSeperator.
Stefan Steinegger
@Stefan You should be checking for Path.DirectorySeparatorChar and Path.AltDirectorySeparatorChar. You are using Path.PathSeparator, which is used to separate path strings in environment variables - normally a semicolon
Joe
@Joe, thanks, fixed it. The AltDirectorySeparatorChar should best be replaced with DirectorySeparatorChar when normalizing, if used anyway.
Stefan Steinegger