Eu preciso reverter o meu NSArray
.
Como um exemplo:
[1,2,3,4,5]
deve se tornar: [5,4,3,2,1]
Qual é a melhor maneira de conseguir isso?
objective-c
nsarray
Andy Jacobs
fonte
fonte
Respostas:
Para obter uma cópia invertida de uma matriz, observe a solução de danielpunkass usando
reverseObjectEnumerator
.Para reverter uma matriz mutável, você pode adicionar a seguinte categoria ao seu código:
fonte
Existe uma solução muito mais fácil, se você tirar proveito do
reverseObjectEnumerator
método interno ativadoNSArray
e doallObjects
método deNSEnumerator
:allObjects
está documentado como retornando uma matriz com os objetos que ainda não foram atravessadosnextObject
, em ordem:fonte
Alguns benchmarks
1. reverseObjectEnumerator allObjects
Este é o método mais rápido:
Resultado:
executionTime = 0.000026
2. Iterando sobre um reverseObjectEnumerator
Isso fica entre 1,5x e 2,5x mais lento:
Resultado:
executionTime = 0.000071
3. selectedArrayUsingComparator
Isso fica entre 30x e 40x mais lento (sem surpresas aqui):
Resultado:
executionTime = 0.001100
Assim
[[anArray reverseObjectEnumerator] allObjects]
é o vencedor claro quando se trata de velocidade e facilidade.fonte
enumerateObjectsWithOptions:NSEnumerationReverse
?enumerateObjectsWithOptions:NSEnumerationReverse
- o primeiro concluído em0.000072
segundos, o método de bloqueio em0.000009
segundos.O DasBoot tem a abordagem correta, mas há alguns erros em seu código. Aqui está um trecho de código completamente genérico que reverterá qualquer NSMutableArray no local:
Você pode agrupar isso em uma função C ou, para pontos de bônus, use categorias para adicioná-lo ao NSMutableArray. (Nesse caso, 'array' se tornaria 'self'.) Você também pode otimizá-lo atribuindo
[array count]
uma variável antes do loop e usando essa variável, se desejar.Se você possui apenas um NSArray regular, não há como revertê-lo, pois o NSArrays não pode ser modificado. Mas você pode fazer uma cópia invertida:
Ou use este pequeno truque para fazer isso em uma linha:
Se você quiser fazer um loop ao longo de uma matriz para trás, poderá usar um loop
for
/ , mas provavelmente será um pouco mais eficiente :in
[array reverseObjectEnumerator]
-enumerateObjectsWithOptions:usingBlock:
( Observação : substancialmente atualizado em 2014, com mais cinco anos de experiência da Fundação, um novo recurso do Objective-C ou dois e algumas dicas dos comentários.)
fonte
Depois de revisar as respostas dos outros acima e encontrar a discussão de Matt Gallagher aqui
Eu proponho isso:
Como Matt observa:
Pouco tempo depois, ele responde assim:
fonte
As categorias de Georg Schölly são muito agradáveis. No entanto, para NSMutableArray, o uso de NSUIntegers para os índices resulta em uma falha quando a matriz está vazia. O código correto é:
fonte
A maneira mais eficiente de enumerar uma matriz ao contrário:
Use
enumerateObjectsWithOptions:NSEnumerationReverse usingBlock
. Usando o benchmark de @ JohannesFahrenkrug acima, isso foi concluído 8 vezes mais rápido que[[array reverseObjectEnumerator] allObjects];
:fonte
fonte
Inverter matriz e fazer um loop através dela:
fonte
Para atualizar isso, no Swift, isso pode ser feito facilmente com:
fonte
Quanto a mim, você considerou como a matriz foi preenchida em primeiro lugar? Eu estava no processo de adicionar MUITOS objetos a uma matriz e decidi inserir cada um no início, empurrando todos os objetos existentes por um. Requer uma matriz mutável, neste caso.
fonte
Ou o Scala-way:
fonte
Existe uma maneira fácil de fazer isso.
Eu espero que isso ajude.
fonte
Não conheço nenhum método embutido. Mas codificar à mão não é muito difícil. Supondo que os elementos da matriz com a qual você está lidando sejam objetos NSNumber do tipo inteiro, e 'arr' seja o NSMutableArray que você deseja reverter.
Desde que você começa com um NSArray, é necessário criar a matriz mutável primeiro com o conteúdo do NSArray original ('origArray').
Edit: Fixed n -> n / 2 na contagem de loop e mudou NSNumber para o ID mais genérico devido às sugestões na resposta de Brent.
fonte
Se tudo o que você deseja fazer é iterar ao contrário, tente o seguinte:
Você pode fazer o [myArrayCount] uma vez e salvá-lo em uma variável local (acho que é cara), mas também acho que o compilador fará a mesma coisa com o código descrito acima.
fonte
Sintaxe do Swift 3:
fonte
Tente o seguinte:
fonte
Aqui está uma boa macro que funcionará para NSMutableArray OU NSArray:
Para usar apenas ligue:
reverseArray(myArray);
fonte