Как я могу получить каталог общего предка для двух или более файлов в Cocoa / Obj-C? - PullRequest
1 голос
/ 17 мая 2010

У меня есть куча файлов, либо NSString s, либо NSURL s (это не имеет значения; по большей части они взаимозаменяемы), и мне нужен способ найти каталог общего предка. Кто-нибудь знает, как это сделать?

Ответы [ 3 ]

4 голосов
/ 17 мая 2010

Я мог бы поклясться, что где-то был метод pathByJoiningPathComponents или хотя бы один такой, но я должен думать о другом. Это делает трюк для путей, он может работать и для URL, если вы используете 10.6 (я тестировал только с путями):

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

Я не думаю, что есть & ldquo; встроенный & rdquo; способ сделать это, к сожалению.

Если у вас есть массив путей к файлам, которые вы хотите найти общего предка, вы можете сделать что-то вроде этого:

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

Возможно, вы захотите явно выделить и освободить некоторые из этих объектов, если хотите поддерживать чистоту пула автоматического выпуска, особенно если у вас большой массив путей.

2 голосов
/ 17 мая 2010

Представляет пути как NSArrays компонентов. (В Mac OS X 10.6 и более поздних версиях отправляйте каждому объекту сообщение pathComponents; в более ранних версиях и в iPhone OS вам нужно будет отправлять сообщения NSURL объектов path, чтобы получить строки NSStrings, а затем отправлять эти pathComponents сообщений.)

Иметь NSMutableArray, содержащий общий путь. Инициализируйте его для компонентов первого пути.

Для каждого последующего пути итерируйте и этот путь, и текущий путь до сих пор в режиме блокировки, используя NSEnumerators.

  • Если общий путь к настоящему времени исчерпан, никаких изменений.
  • Если путь, который вы исследуете, заканчивается, это новый общий путь.
  • Если вы столкнулись с неравным компонентом, все компоненты перед ним - это новый общий путь. Прервите итерацию локстепа здесь.

Когда вы закончите, у вас будет массив из нуля или более компонентов пути. Объединение их в строку абсолютного пути приведет к появлению строки общего пути.

1 голос
/ 17 мая 2010

Возьмите файл, возьмите следующий файл, итерируйте по его предкам (метод NSString pathComponents будет полезен для этого), пока не найдете тот, который у них общий. Затем перейдите к следующему файлу, посмотрите, есть ли у него тот же предок. Если нет, продолжайте возвращаться, пока не найдете тот, который у них есть общего. Продолжайте повторять это, пока не дойдете до конца списка.

...