¿Cómo puedo obtener el directorio ancestro común por dos o más archivos en Cocoa / Obj-C?

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

Pregunta

Tengo un montón de archivos, ya sea NSStrings o NSURLs (no importa, sino que son, en su mayor parte, intercambiable), y necesito una manera de encontrar el directorio ancestro común. ¿Alguien sabe cómo hacer esto?

¿Fue útil?

Solución

Yo podría haber jurado que había un método en algún lugar pathByJoiningPathComponents, o al menos uno igual, pero debe estar pensando en otra cosa. Esto hace el truco para las rutas, puede funcionar para las direcciones URL también si estás en 10.6 (sólo le he probado con caminos):

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

No creo que hay un “built-in” forma de hacerlo, por desgracia.

Si usted tiene una serie de rutas de archivo que desea encontrar el ancestro común, que podría hacer algo como esto:

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

Es posible que desee asignar y liberar algunos de estos objetos si se quiere mantener la piscina limpia autorelease explícitamente, sobre todo si se tiene una gran variedad de caminos.

Otros consejos

representan la caminos como NSArrays de componentes. (En Mac OS X 10.6 y posteriores, envíe un mensaje cada objeto pathComponents; en las versiones anteriores y en el iPhone OS, se tendrá que enviar mensajes de objetos NSURL path para obtener NSStrings, a continuación, enviar los mensajes de los pathComponents.)

Tener una NSMutableArray que contiene la ruta común hasta ahora. Inicializar a los componentes de la primera trayectoria.

Para cada trayectoria posterior, iterate tanto ese camino y la trayectoria de corriente hasta el momento en Lockstep usando NSEnumerators.

  • Si el camino común hasta ahora se agota, no hay cambio.
  • Si la ruta que está examinando se agota, es el nuevo camino común.
  • Si se encuentra con un componente inequal, todos los componentes antes de ella son el nuevo camino común. Romper la iteración mismo paso aquí.

Cuando termine, tendrá un conjunto de cero o más componentes de la ruta. La unión de estos en una cadena de ruta absoluta producirá la cadena de ruta común.

Tome un archivo, dar el siguiente archivo, iterar a través de sus antepasados ??(método pathComponents de NSString será útil para esto) hasta que encuentre uno que tienen en común. A continuación, pasar a la siguiente archivo, ver si tiene el mismo ancestro. Si no es así, seguir yendo hasta que encuentre uno que sí tienen en común. Sigue repitiendo esto hasta que llegue al final de la lista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top