Comment puis-je obtenir le répertoire ancêtre commun pour deux ou plusieurs fichiers à Cocoa / Obj-C?

StackOverflow https://stackoverflow.com/questions/2845974

Question

J'ai un tas de fichiers, que ce soit NSStrings ou NSURLs (il n'a pas d'importance, ils sont, pour la plupart, interchangeables), et je besoin d'un moyen de trouver le répertoire ancêtre commun. Quelqu'un sait comment faire?

Était-ce utile?

La solution

Je aurait pu jurer qu'il y avait un endroit de méthode pathByJoiningPathComponents, ou au moins un comme ça, mais je dois penser à autre chose. Cela fait le tour des chemins, il peut fonctionner pour les URL trop si vous êtes sur 10.6 (je ne testé avec des chemins):

NSString *path1 = @"/path/to/file1.txt";
NSString *path2 = @"/path/to/file/number2.txt";

NSArray *path1Comps = [path1 pathComponents];
NSArray *path2Comps = [path2 pathComponents];

NSUInteger total = [path1Comps count];
if ([path2Comps count] < total)
    total = [path2Comps count];  // get the smaller of the two

NSUInteger i;
for (i = 0; i < total; i++)
    if (![[path1Comps objectAtIndex:i] isEqualToString:[path2Comps objectAtIndex:i]])
        break;

NSArray *commonComps = [path1Comps subarrayWithRange:NSMakeRange(0, i)];

// join commonComps together to get the common path as a string

Je ne pense pas qu'il y ait un « intégré » façon de le faire, malheureusement.

Si vous avez un tableau de chemins de fichiers que vous voulez trouver l'ancêtre commun, vous pouvez faire quelque chose comme ceci:

NSArray *allPaths = [NSArray arrayWithObjects:@"/path/to/1.txt", @"/path/to/number/2.txt", @"/path/to/number/3/file.txt", nil];

// put some checks here to make sure there are enough paths in the array.

NSArray *currentCommonComps = [[allPaths objectAtIndex:0] pathComponents];

for (NSUInteger i = 1; i < [allPaths count]; i++)
{
    NSArray *thisPathComps = [[allPaths objectAtIndex:i] pathComponents];
    NSUInteger total = [currentCommonComps count];
    if ([thisPathComps count] < total)
        total = [thisPathComps count];

    NSUInteger j;
    for (j = 0; j < total; j++)
        if (![[currentCommonComps objectAtIndex:j] isEqualToString:[thisPathComps objectAtIndex:j]])
            break;

    if (j < [currentCommonComps count])
        currentCommonComps = [currentCommonComps subarrayWithRange:NSMakeRange(0, j)];

    if ([currentCommonComps count] == 0)
        break; // no point going on
}

// join currentCommonComps together

Vous voudrez peut-être allouer explicitement et libérer certains de ces objets si vous voulez garder la piscine autorelease propre, surtout si vous avez un large éventail de chemins.

Autres conseils

Représenter les chemins que NSArrays des composants. (Sous Mac OS X 10.6 et plus tard, envoyer chaque objet un message pathComponents, dans les versions antérieures et sur l'iPhone OS, vous devez envoyer NSURL objets messages path pour obtenir NSStrings, puis envoyer ces messages de pathComponents.)

Avoir un NSMutableArray contenant le chemin commun jusqu'à présent. Initialiser aux composants du premier chemin.

Pour chaque chemin suivant, à la fois itérer cette voie et le chemin courant jusqu'à présent au même rythme que l'utilisation NSEnumerators.

  • Si le chemin commun afin court loin, pas de changement.
  • Si le chemin que vous examinez MANQUE, il est le nouveau chemin commun.
  • Si vous rencontrez un composant inégalitaire, tous les composants avant qu'il sont le nouveau chemin commun. Briser l'itération même rythme ici.

Lorsque vous avez terminé, vous aurez un tableau de zéro ou plusieurs composants de chemin. Rejoindre ceux-ci dans une chaîne de chemin absolu produira la chaîne de chemin commun.

Prenez un fichier, prenez le fichier suivant, itérer à travers ses ancêtres (méthode de pathComponents de NSString sera utile pour cela) jusqu'à ce que vous trouviez un qui qu'ils ont en commun. Ensuite, passez sur le fichier suivant, voir si elle a le même ancêtre. Sinon, continuez de retourner jusqu'à ce que vous trouviez celui qu'ils ont en commun. Continuez à répéter jusqu'à ce que vous atteignez la fin de la liste.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top