Necesito revertir mi NSArray
.
Como ejemplo:
[1,2,3,4,5]
debe convertirse en: [5,4,3,2,1]
¿Cuál es la mejor manera de lograr esto?
objective-c
nsarray
Andy Jacobs
fuente
fuente
Respuestas:
Para obtener una copia invertida de una matriz, mira la solución de danielpunkass usando
reverseObjectEnumerator
.Para invertir una matriz mutable, puede agregar la siguiente categoría a su código:
fuente
Hay una solución mucho más fácil, si aprovecha el
reverseObjectEnumerator
método incorporadoNSArray
y elallObjects
método deNSEnumerator
:allObjects
está documentado como devolver una matriz con los objetos que aún no se han recorridonextObject
, en orden:fuente
Algunos puntos de referencia
1. reverseObjectEnumerator allObjects
Este es el método más rápido:
Resultado:
executionTime = 0.000026
2. Iterando sobre un reverseObjectEnumerator
Esto es entre 1.5x y 2.5x más lento:
Resultado:
executionTime = 0.000071
3. sortedArrayUsingComparator
Esto es entre 30x y 40x más lento (sin sorpresas aquí):
Resultado:
executionTime = 0.001100
Así
[[anArray reverseObjectEnumerator] allObjects]
es el claro ganador cuando se trata de velocidad y facilidad.fuente
enumerateObjectsWithOptions:NSEnumerationReverse
?enumerateObjectsWithOptions:NSEnumerationReverse
: el primero completado en0.000072
segundos, el método de bloqueo en0.000009
segundos.DasBoot tiene el enfoque correcto, pero hay algunos errores en su código. Aquí hay un fragmento de código completamente genérico que revertirá cualquier NSMutableArray en su lugar:
Puede ajustar eso en una función C, o para puntos de bonificación, use categorías para agregarlo a NSMutableArray. (En ese caso, 'array' se convertiría en 'self'). También puede optimizarlo asignándolo
[array count]
a una variable antes del ciclo y utilizando esa variable, si lo desea.Si solo tiene un NSArray regular, no hay forma de revertirlo en su lugar, porque los NSArray no pueden modificarse. Pero puedes hacer una copia invertida:
O use este pequeño truco para hacerlo en una línea:
Si solo desea recorrer una matriz hacia atrás, puede usar un
for
/in
loop con[array reverseObjectEnumerator]
, pero es probable que sea un poco más eficiente de usar-enumerateObjectsWithOptions:usingBlock:
:( Nota : sustancialmente actualizado en 2014 con cinco años más de experiencia de la Fundación, una nueva característica de Objective-C o dos, y un par de consejos de los comentarios).
fuente
Después de revisar las respuestas del otro arriba y encontrar la discusión de Matt Gallagher aquí
Propongo esto:
Como Matt observa:
Poco después, responde así:
fuente
Las categorías de Georg Schölly son muy agradables. Sin embargo, para NSMutableArray, el uso de NSUIntegers para los índices da como resultado un bloqueo cuando la matriz está vacía. El código correcto es:
fuente
La forma más eficiente de enumerar una matriz en reversa:
Uso
enumerateObjectsWithOptions:NSEnumerationReverse usingBlock
. Usando el punto de referencia de @ JohannesFahrenkrug anterior, esto se completó 8 veces más rápido que[[array reverseObjectEnumerator] allObjects];
:fuente
fuente
Matriz inversa y recorrerla:
fuente
Para actualizar esto, en Swift se puede hacer fácilmente con:
fuente
En cuanto a mí, ¿has considerado cómo se pobló la matriz en primer lugar? Estaba en el proceso de agregar MUCHOS objetos a una matriz, y decidí insertar cada uno al principio, empujando los objetos existentes hacia arriba uno por uno. Requiere una matriz mutable, en este caso.
fuente
O el camino de escala:
fuente
Hay una manera fácil de hacerlo.
Espero que esto ayude.
fuente
No conozco ningún método incorporado. Pero, la codificación a mano no es demasiado difícil. Suponiendo que los elementos de la matriz con la que está tratando son objetos NSNumber de tipo entero, y 'arr' es el NSMutableArray que desea revertir.
Como comienza con un NSArray, primero debe crear la matriz mutable con el contenido del NSArray original ('origArray').
Editar: Se corrigió n -> n / 2 en el recuento del bucle y se cambió NSNumber a la identificación más genérica debido a las sugerencias en la respuesta de Brent.
fuente
Si todo lo que quiere hacer es iterar en reversa, intente esto:
Puede hacer [myArrayCount] una vez y guardarlo en una variable local (creo que es costoso), pero también supongo que el compilador hará lo mismo con el código que se escribió anteriormente.
fuente
Sintaxis de Swift 3:
fuente
Prueba esto:
fuente
Aquí hay una buena macro que funcionará para NSMutableArray O NSArray:
Para usar solo llame:
reverseArray(myArray);
fuente