2010-06-10 4 views
4

Dire que j'ai cette listeC# supprimer des chemins redondants à partir d'une liste

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

Je voudrais supprimer les chemins qui sont contenus dans d'autres dossiers, par exemple, nous avons C: \ Dossier1 et C: \ Dossier1 \ Folder3

troisième entrée de la liste devrait aller parce que C: \ Dossier1 contient C: \ Dossier1 \ Folder3

est là quelque chose qui fait que, dans le cadre de .net ou dois-je écrire moi-même algo?

Répondre

2

En supposant que ce n'est pas une liste énorme.

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(); 
+0

Vous faites un peu de travail en fonction de 's.EndsWith (sep)', efficacement dans une boucle. Il est probablement plus propre et plus facile de normaliser les entrées au préalable. – MSalters

+0

Je me rends compte qu'il y a des façons de le rendre plus efficace ainsi le "En supposant que ce n'est pas une liste énorme." – Don

-3

Vous devriez faire vous-même. Pensez-vous que .net a implémenté une méthode pour faire une telle tâche spécifique? Utilisez des méthodes de chaîne.

+1

probablement pas, mais je me attendais aurait-il une méthode comme Path1. isIn (Path2) - comme "C: \ Folder1 \ Folder3" .isIn ("C: \ Folder1") => vrai –

+0

il n'y a pas une telle méthode. Parce que chemin est juste une chaîne, utilisez des méthodes de chaîne comme StartsWith (comme dit @Stefan) – erasmus

+1

En fait, un chemin est plus d'une chaîne. Considérez les points de montage. D: \ pourrait être le même chemin que C: \ SecondDisk \ – MSalters

3

je plus probablement utiliserais opérations de chaîne sur les chaînes de chemins normalisés:

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

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

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

exemple complet:

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)); 
+1

Vous devez vous assurer que GetFullPath est terminé avec une barre oblique inverse, sinon 'C: \\ Folder1' va" masquer "' C: \\ Folder11' – peterchen

+0

Accepter 'Path.GetFullPath' selon la source des chaînes dans le premier placer mais 'ToLower()' gâcherait sur des partages Linux, mono ou samba (?), cela n'empêche pas les répertoires avec des différences de casse je pense. – Don

+0

@Don, oui, c'est ma recommandation "en fonction de os ...". Je ne sais pas si vous pouvez savoir si les chemins sont sensibles à la casse ou non, ce code n'est qu'un exemple. –

Questions connexes