2009-06-17 14 views
9

En Objective C, ¿hay un trazador de líneas o algo pequeño para eliminar (acortar por uno) y devolver el primer elemento de un conjunto, independientemente de su índice?¿Cómo puedo eliminar el primer elemento de una matriz en Objective C?

+0

¿Está hablando de un conjunto desnudo de estilo C, o algo así como un NSArray/NSMutableArray? –

+1

En el caso de una matriz de estilo C desnuda, tiene problemas antes de salir de la puerta de entrada: las matrices de estilo C no incluyen sus límites/información de tamaño válido. Supongo que podría pasar un puntero al tamaño válido, pero eso se pone feo ... –

+1

Por otra parte, para una matriz estilo C, * p ++ logra algo muy parecido a un cambio. –

Respuesta

19

No conozco un método que devuelva el elemento eliminado, pero puede hacerlo utilizando una combinación de NSArray#objectAtIndex:0 y NSMutableArray#removeObjectAtIndex:0. Supongo que podría introducir una nueva categoría de método en NSMutableArray que implementa un método shift.

+0

Tenía la impresión de que cuando eliminéObjectAtIndex: 0 me quedaría una matriz que comenzaba con un índice de 1, como puede encontrar en PHP. Pero resulta que superarlo (es el más viejo que agregué a la matriz) es suficiente para lo que estoy haciendo. – ojreadmore

+1

La documentación vinculada dice que se comporta de manera similar al desplazamiento, deslizando los otros elementos hacia abajo. –

+0

Si realmente desea una sola llamada a un método, consulte mi respuesta para obtener una declaración de categoría de muestra que agrega lo que necesita. –

1

Los objetos de matriz de cacao (NSArray/NSMutableArray) no proporcionan un equivalente de una línea: primero debe leer el objeto y luego quitarlo. El hecho de que estas clases proporcionen los métodos -lastObject y -removeLastObject pero no -firstObject y -removeFirstObject debe ser un recordatorio de que eliminar del frente de una matriz generalmente es una operación ineficiente, ya que el contenido debe desplazarse (copiarse) una posición hacia adelante. Esto es particularmente cierto para las matrices en C, que están vinculadas intrínsecamente con punteros.

Si está trabajando con algo más que tipos de datos primitivos y/o arreglos muy pequeños, puede considerar que el comportamiento de "cambiar el primer elemento" es indicativo de un queue data structure. Para obtener detalles sobre cómo puede crear una cola para objetos, consulte this SO question. Personalmente, my opinion for that question es que una clase de cola real proporciona la expresión de programación más limpia. Incluso puede definir su propio método (tal vez como una categoría en NSMutableArray o de otra clase) que qué proporcionan una sola línea para hacer lo que desee:

@interface NSMutableArray (QueueOneLiner) 
    - (id) removeAndReturnFirstObject; // Verbose, but clearer than "shift" 
@end 

@implementation NSMutableArray (QueueOneLiner) 
    - (id) removeAndReturnFirstObject { 
    id object = [[self objectAtIndex:0] retain]; 
    [self removeObjectAtIndex:0]; 
    return [object autorelease]; 
    } 
@end 

Sin embargo, en ese momento la solución probablemente causará más sobrecarga de lo que vale, dependiendo de la importancia que le dé a la simplicidad frente al rendimiento del código que la usa.

+1

Su QueueOneLiner puede devolver un objeto no válido. RemoveObjectAtIndex: 0 lanzará el "objeto" que puede desasignarlo prematuramente si no se utiliza la recolección de elementos no utilizados. Debería retener y luego liberar automáticamente el objeto antes de eliminarlo de la matriz. – dreamlax

+0

¡Un excelente punto! Editado para incluir su sugerencia. –

3

Eso sería una cosa pobre de hacer.

Objective-C en el iPhone en realidad puede utilizar la mayoría de las ventajas de rendimiento de C.

Si nos fijamos en algunos de mis otros mensajes, verá que estoy rotundamente en contra de la optimización prematura, pero cuando están codificando en el nivel C, solo hay algunas cosas que no se hacen innecesariamente.

  • memoria Mover
  • estructuras duplicadas
  • destinar escasamente pobladas bloques de memoria bucles
  • interior
  • ... (Hay muchos más, pero mi vida es C-oxidada y, como dije , Soy anti-optimización)

Lo que probablemente desee es una cola bien implementada. Algo que preasigna una estructura de memoria circular lo suficientemente grande y luego tiene dos punteros que rastrean el primer y el último byte.

Me sorprendería mucho escuchar que Objective-C no tenía una estructura de datos en cola.

Además, no se esfuerce por los one-liners. Todo lo relacionado con el código temporal está sobrevalorado. Si tiene más sentido llamar a un método, que así sea.

+0

perl "arrays" son más como una cola bien implementada que una matriz C; han almacenado desplazamientos a los "primeros" y últimos elementos y preasignan de forma inteligente cuando sea necesario. – ysth

+0

Razón de más para usar una cola en Objective-C entonces. La mayoría de los lenguajes interpretados son alrededor de 100 veces más lentos que los lenguajes compilados; a ese ritmo, las preocupaciones son completamente diferentes y tiene sentido que todas las matrices tengan la sobrecarga de una cola, pero no encontrarás nada parecido en la C idiomas basados ​​en –

1

Si tiene una matriz obj *arr donde obj es una clase/nombretipo y arr es la matriz, que sólo puede decir arr+1 para obtener la matriz sin el primer elemento.

0

utilizar este código,

[arrayName removeObjectAtIndex:0]; 

esto puede ayudarle a

+0

Esto no proporciona ninguna información útil adicional que la respuesta aceptada no haya proporcionado, y solo funcionará en el caso de un 'NSMutableArray' (no' NSArray') – Stonz2

0

Es sin duda demasiado tarde para ayudar a su creador original, pero si usted tiene un NSArray sencilla y no es una NSMutableArray, esto funciona así:

id myData = myArray.firstObject; 
myArray = [myArray subarrayWithRange:NSMakeRange(1, myArray.count - 1)]; 
+0

A menos que su matriz tenga solo un elemento, en cuyo caso su valor 'loc' de 1 está fuera del' NSArray' y usted arroja 'NSRangeException' – SDJMcHattie

Cuestiones relacionadas