Slice NSArray desde el final de la matriz

¿Cuál es la mejor manera de "dividir" un NSArray desde el final, en lugar del principio, de la matriz (por ejemplo, encontrar el subarray que contiene los últimos elementos de un NSArray de longitud desconocida)? En Python, puedes usar índices negativos para lograr esto, por ejemplo:

 new_list = old_list[-5:-3] 

¿Cuál es la forma más natural de hacer esto en Objective-C?

No hay nada que coincida con la buena syntax de Python para esto, pero puedes hacer lo siguiente:

 NSUInteger count = [myArray count]; NSArray * slice = [myArray subarrayWithRange:(NSRange){count-n, n}]; 

También podría escribir una categoría para NSArray , algo así como:

 @interface NSArray (jrdioko_slice) - (NSArray *) jrdioko_sliceFrom:(NSInteger)start to:(NSInteger)stop; @end 

Si quieres seguir esta ruta, la fuente de Python ciertamente reembolsará el estudio. Un object de list crea un object de split cuando se realiza una operación de split. El método relevante en un object de PySlice_GetIndicesEx es PySlice_GetIndicesEx . Deberás tener cuidado al convertir esos índices en un NSRange . Como el comentario en esa function advierte "esto es más difícil de lo que puede pensar". (Trataré de descifrar esto más adelante.)

ACTUALIZACIÓN: aquí tenemos una categoría de cortes en NSArray . La lógica de cálculo del índice está más o less directamente del código de Python que enlazé anteriormente. * En realidad, es mucho más fácil de lo que pensé al principio si no tienes que preocuparte por la parte stride de una porción de Python. He ejecutado esto a través de algunas testings y parece funcionar igual que la versión de Python.

 @interface NSArray (WSS_Slice) - (NSArray *)WSS_arrayBySlicingFrom:(NSInteger)start to:(NSInteger)stop; @end // Python allows skipping any of the indexes of a slice and supplies default // values. Skipping an argument to a method is not possible, so (ab)use // NSNotFound as "not specified" index value. The other way to do this would // be with varargs, which might be even handier if one decided to implement // the stride functionality. enum { WSS_SliceNoIndex = NSNotFound }; @implementation NSArray (WSS_Slice) - (NSArray *)WSS_arrayBySlicingFrom:(NSInteger)start to:(NSInteger)stop { // There's an important caveat here: specifying the parameters as // NSInteger allows negative indexes, but limits the method's // (theoretical) use: the maximum size of an NSArray is NSUIntegerMax, // which is quite a bit larger than NSIntegerMax. NSUInteger count = [self count]; // Due to this caveat, bail if the array is too big. if( count >= NSIntegerMax ) return nil; // Define default start and stop NSInteger defaultStart = 0; NSInteger defaultStop = count; // Set start to default if not specified if( start == WSS_SliceNoIndex ){ start = defaultStart; } else { // If start is negative, change it to the correct positive index. if( start < 0 ) start += count; // Correct for out-of-bounds index: // If it's _still_ negative, set it to 0 if( start < 0 ) start = 0; // If it's past the end, set it to just include the last item if( start > count ) start = count; } // Perform all the same calculations on stop if( stop == WSS_SliceNoIndex ){ stop = defaultStop; } else { if( stop < 0 ) stop += count; if( stop < 0 ) stop = 0; if( stop > count ) stop = count; } // Calculate slice length with corrected indexes NSInteger sliceLength = stop - start; // If no slice, return a new empty array if( sliceLength <= 0 ){ return [NSArray array]; } else { return [self subarrayWithRange:(NSRange){start, sliceLength}]; } } @end 

* Por lo tanto, creo que necesito include un enlace a la Licencia de Python y también señalar que esto puede seguir siendo "Copyright © 2001-2010 Python Software Foundation; Todos los derechos reservados ", porque aunque esto me parece un trabajo derivado separado por derecho de autor, no soy un abogado.