2009-06-17 15 views
9

In Objective C, c'è un one-liner o qualcosa di piccolo da rimuovere (accorciamento di uno) e restituisce il primo elemento di un array, indipendentemente dal suo indice?Come posso rimuovere il primo elemento di un array nell'obiettivo C?

+0

Stai parlando di un array in stile C o qualcosa di simile a un NSArray/NSMutableArray? –

+1

Nel caso di un array in stile C scarso, ci si trova in difficoltà prima di uscire dal gate: gli array in stile C non includono i relativi limiti/informazioni sulle dimensioni valide. Suppongo che potresti passare un puntatore alle dimensioni valide, ma questo diventa brutto ... –

+1

Quindi, per un array in stile C, * p ++ realizza qualcosa di molto simile a un turno. –

risposta

19

Non so un metodo che restituisce l'elemento rimosso, ma è possibile farlo utilizzando una combinazione di NSArray#objectAtIndex:0 e NSMutableArray#removeObjectAtIndex:0. Suppongo che potresti introdurre una nuova categoria di metodi su NSMutableArray che implementa un metodo shift.

+0

Ho avuto l'impressione che quando ho rimossoObjectAtIndex: 0 mi sarebbe rimasta una matrice che iniziava con un indice di 1, come si può trovare in PHP. Ma a quanto pare, eliminarlo (essendo il più vecchio che ho aggiunto all'array) è abbastanza per quello che sto facendo. – ojreadmore

+1

La documentazione collegata dice che si comporta in modo simile allo spostamento, facendo scorrere gli altri elementi verso il basso. –

+0

Se si desidera realmente una chiamata al metodo singolo, vedere la mia risposta per una dichiarazione di categoria di esempio che aggiunge ciò che è necessario. –

1

Gli oggetti array di cacao (NSArray/NSMutableArray) non forniscono un equivalente a una riga: è necessario prima leggere l'oggetto, quindi rimuoverlo. Il fatto che queste classi forniscano i metodi -lastObject e -removeLastObject ma non -firstObject e -removeFirstObject dovrebbe ricordare che la rimozione dalla parte anteriore di un array è di solito un'operazione inefficace, poiché il contenuto deve essere spostato (copiato) in avanti di una posizione. Questo è particolarmente vero per gli array in C, che sono intrinsecamente legati ai puntatori.

Se si sta lavorando con qualsiasi tipo di dati primitivi e/o con array molto piccoli, è possibile considerare che il comportamento di "spostamento" del primo elemento è indicativo di queue data structure. Per dettagli su come creare una coda per gli oggetti, vedere this SO question. Personalmente, my opinion for that question è che una vera classe di coda fornisce l'idioma di programmazione più pulito. È anche possibile definire un proprio metodo (forse come una categoria a NSMutableArray o un'altra classe) che fa fornire un one-liner per fare ciò che si vuole:

@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 

Tuttavia, a quel punto la soluzione probabile causa più spese generali di quelle che valgono, a seconda dell'importanza che si attribuisce alla semplicità rispetto alle prestazioni del codice che la utilizza.

+1

QueueOneLiner potrebbe restituire un oggetto non valido. Il removeObjectAtIndex: 0 rilascerà "oggetto" che potrebbe dealarlo prematuramente se non viene utilizzata la garbage collection. È necessario conservare e quindi autorizzare automaticamente l'oggetto prima di rimuoverlo dall'array. – dreamlax

+0

Un punto eccellente! Modificato per includere il tuo suggerimento. –

3

Sarebbe una cosa mediocre da fare.

Objective-C su iPhone può effettivamente utilizzare la maggior parte dei vantaggi di prestazioni di C.

Se si guarda ad alcuni dei miei altri post, vedrai che sono categoricamente contro ottimizzazione prematura, ma quando stai programmando a livello C, ci sono solo alcune cose che non fai inutilmente.

  • memoria Spostare
  • strutture duplicate
  • allocare scarsamente popolate blocchi di memoria
  • interno loop
  • ... (Ci sono un sacco di più, ma la mia C-vita è arrugginito e, come ho detto , Sono anti-ottimizzazione)

Ciò che si desidera è una coda ben implementata. Qualcosa che pre-alloca una struttura di memoria circolare abbastanza grande e quindi ha due puntatori che tracciano il primo e l'ultimo byte.

Sarei piuttosto sorpreso di sentire che Objective-C non aveva una struttura dati della coda.

Inoltre, non sforzarsi per le one-liner. Tutta la roba sul codice terse è sopravvalutata. Se ha più senso chiamare un metodo, così sia.

+0

perl "array" sono più come una coda ben implementata che una matrice C; hanno memorizzato le correzioni al "primo" e all'ultimo elemento e preallocato in modo intelligente dove necessario. – ysth

+0

Un motivo in più per usare una coda su Objective-C quindi. Le lingue più interpretate sono circa 100 volte più lente delle lingue compilate - a quel ritmo, le preoccupazioni sono completamente diverse e ha senso che tutti gli array abbiano il sovraccarico di una coda, ma non troverete nulla di simile nella C lingue basate su –

1

Se si dispone di una matrice in cui obj *arrobj è una classe/TypeName e arr è la matrice, si può solo dire arr+1 per ottenere la matrice senza il primo elemento.

0

utilizzare questo codice,

[arrayName removeObjectAtIndex:0]; 

questo può aiutare

+0

Questo non fornisce alcuna informazione utile aggiuntiva che la risposta accettata non ha già fornito, e funzionerà solo nel caso di un 'NSMutableArray' (non' NSArray') – Stonz2

0

E 'certamente troppo tardi per aiutare il manifesto originale, ma se si dispone di una pianura NSArray e non un NSMutableArray, questo funziona bene:

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

A meno che l'array abbia solo un elemento in esso, nel qual caso il valore 'loc' di 1 è esterno a quello di' NSArray' e si lancia un 'NSRangeException' – SDJMcHattie

Problemi correlati