2011-11-30 1 views
6

Sto cercando di utilizzare NSRange per tenere una serie di anni, come ad esempioLooping utilizzando NSRange

NSRange years = NSMakeRange(2011, 5); 

So NSRange viene utilizzato per lo più per il filtraggio, tuttavia voglio ciclo sugli elementi della gamma. È possibile senza convertire NSRange in un NSArray?

risposta

8

E 'sorta di suona come vi aspettate NSRange ad essere come un range oggetto Python. Non è; NSRange è semplicemente una struct

typedef struct _NSRange { 
     NSUInteger location; 
     NSUInteger length; 
} NSRange; 

non un oggetto. Dopo aver creato uno, è possibile utilizzare i suoi membri in una pianura vecchio for ciclo:

NSUInteger year; 
for(year = years.location; year < NSMaxRange(years); year++){ 
    // Do your thing. 
} 

(ancora lavorando sul presupposto che si sta pensando di Python.) C'è sintassi objC chiamato fast enumeration per iterare su il contenuto di un NSArray che è piacevolmente simile a un loop Python for, ma poiché i numeri letterali e primitivi non possono essere inseriti in un NSArray, non è possibile passare direttamente da un NSRange a un array Cocoa.

Una categoria potrebbe fare che facile, però:

@implementation NSArray (WSSRangeArray) 

+ (id)WSSArrayWithNumbersInRange:(NSRange)range 
{ 
    NSMutableArray * arr = [NSMutableArray array]; 
    NSUInteger i; 
    for(i = range.location; i < NSMaxRange(range); i++){ 
     [arr addObject:[NSNumber numberWithUnsignedInteger:i]]; 
    } 

    return arr; 
} 

Quindi è possibile creare un array e utilizzare l'enumerazione veloce:

NSArray * years = [NSArray WSSArrayWithNumbersInRange:NSMakeRange(2011, 5)]; 
for(NSNumber * yearNum in years){ 
    NSUInteger year = [yearNum unsignedIntegerValue]; 
    // and so on... 
} 
+0

grazie, troppo male non c'è supporto per l'enumerazione veloce per NSRange. potrebbe salvarmi un po 'di tempo e code line – aporat

+0

@manroe: Apprezzo la tua correzione del mio errore di codifica, ma il grande blocco "EDIT:" era inappropriato; potrebbe essere stato un commento, il riassunto della modifica, o davvero lasciato fuori del tutto. –

6

Ricordare che un NSRange è una struttura che contiene due interi, che rappresentano l'inizio e la lunghezza dell'intervallo. Puoi facilmente eseguire il loop su tutti gli interi contenuti utilizzando un ciclo for.

NSRange years = NSMakeRange(2011, 5); 
NSUInteger year; 
for(year = years.location; year < years.location + years.length; ++year) { 
    // Use the year variable here 
} 
3

Questo è un po 'di una vecchia questione, ma un'alternativa per utilizzare un NSArray sarebbe quello di creare un NSIndexSet con l'intervallo desiderato (utilizzando indexWithIndexesInRange: o initWithIndexesInRange:) e quindi utilizzare l'enumerazione di blocchi come in https://stackoverflow.com/a/4209289/138772. (Sembrava pertinente visto che stavo verificando da solo.)

0

La mia soluzione alternativa per questo era di definire una macro solo per rendere più veloce la stenografia.

#define NSRangeEnumerate(i, range) for(i = range.location; i < NSMaxRange(range); ++i) 

Per chiamare voi:

NSArray *array = @[]; // must contain at least the following range... 
NSRange range = NSMakeRange(2011, 5); 
NSUInteger i; 
NSRangeEnumerate(i, range) { 
    id item = array[i]; 
    // do your thing 
} 

personalmente sto ancora cercando di capire come posso scrivere la macro in modo da poter chiamare le cose come:

NSRangeEnumerate(NSUInteger i, range) { 

} 

che non è ancora supportato ... spero che questo aiuti o faccia più veloce la digitazione del tuo programma