2009-12-04 12 views
28

Ho una domanda sull'ordinamento NSMutableArray. Posso usare il metodo sortedArrayUsingDescriptors: per ordinare un array con oggetti.Come ordinare NSMutableArray utilizzando ordinatiArrayUsingDescriptors?

Per esempio io ho un NSMutableArray di places dove ho un frequency (int value) di attributo e voglio Ordinamento decrescente sulla frequency ma non so come usarlo correttamente.

Cosa inserisco come chiave in initWithKey?

mio oggetto place contiene:

NSString * name; 
NSString * address; 
NSString * frequency; 
NSString * type; 

NSMutableArray * places; 

... populate array with objects ... 

NSSortDescriptor * sortByFrequency = 
    [[[NSSortDescriptor alloc] initWithKey:@"????????" ascending:NO] autorelease]; 

NSArray * descriptors = [NSArray arrayWithObject:sortByFrequency]; 
NSArray * sorted = [x sortedArrayUsingDescriptors:descriptors]; 
+6

Argh! Questo è difficile da capire. Per favore, babyDeveloper, usa la punteggiatura (principalmente punti e virgole) nelle tue domande. – pmg

+3

Hai detto che "frequenza" è un valore int, ma il tuo codice dice che è una NSString. Per favore, fai attenzione a esprimere chiaramente le tue domande. – Chuck

risposta

1

Ecco come un aspirante ordinare un NSMutableArray:

NSMutableArray *numberSort =[[NSMutableArray alloc] init]; 

    while ((key = [enumerator nextObject])) { 
     //(NSNumber *)integer = [key integerValue]; 
     [numberSort addObject:[NSNumber numberWithInt:[key intValue]]]; 
     // code that uses the returned key 
    } 


    NSArray *stringSort = [numberSort sortedArrayUsingSelector:@selector(compare:)]; 
    enumerator = [stringSort objectEnumerator]; 
    NSNumber *intKey; 

    NSMutableArray *backToString =[[NSMutableArray alloc] init]; 

    while ((intKey = [enumerator nextObject])) { 
     //(NSNumber *)integer = [key integerValue]; 
     [backToString addObject:[intKey stringValue]]; 
     // code that uses the returned key 
2

La "chiave" è un metodo di oggetti (il elementi del tuo array "x") che restituisce la cosa che vuoi ordinare. Quindi in questo caso hai detto che vuoi ordinare secondo la "frequenza". Quindi tutto ciò che devi fare è usare il nome del metodo che restituisce la frequenza, come chiave.

+0

Anche se dovrebbe essere di tipo numerico, come 'int' (preferibilmente' unsigned'), 'NSUInteger',' double', o 'NSNumber *'. Con i valori di frequenza come stringhe, non verranno ordinate numericamente (non senza un comparatore personalizzato, comunque). –

110

Per ordinare l'array di oggetti:

  1. impostazione NSSortDescriptor - usare i nomi delle variabili come chiavi di descrittore di configurazione per l'ordinamento, più il selettore per essere eseguito su quei tasti
  2. ottenere la matrice di descrittori utilizzando NSSortDescriptor che hai impostazione
  3. sorta l'array in base a tali descrittori

Ecco due esempi, uno utilizzando NSDictionary e NSString/NSNumber ordinamento dei valori su NSNumber, l'altro con classe personalizzata con ordinamento su due campi NSString.

Seguire gli argomenti di programmazione del cacao Sorting and Filtering NSArray Objects per ulteriori esempi e spiegazioni.

Esempio:

Questo è stato fatto su GNUStep dovrebbe funzionare lo stesso su di cacao - il codice è esattamente lo stesso - Cercherò quando mi siedo davanti al mio Mac:

primo esempio utilizzando NSString e NSNumber valori con l'ordinamento su NSNumber valore:

NSString * NAME  = @"name"; 
NSString * ADDRESS = @"address"; 
NSString * FREQUENCY = @"frequency"; 
NSString * TYPE  = @"type"; 

NSMutableArray * array = [NSMutableArray array]; 

NSDictionary * dict; 

dict = [NSDictionary dictionaryWithObjectsAndKeys: 
      @"Alehandro", NAME, @"Sydney", ADDRESS, 
      [NSNumber numberWithInt:100], FREQUENCY, 
      @"T", TYPE, nil]; 
[array addObject:dict]; 

dict = [NSDictionary dictionaryWithObjectsAndKeys: 
      @"Xentro", NAME, @"Melbourne", ADDRESS, 
      [NSNumber numberWithInt:50], FREQUENCY, 
      @"X", TYPE, nil]; 
[array addObject:dict]; 

dict = [NSDictionary dictionaryWithObjectsAndKeys: 
      @"John", NAME, @"Perth", ADDRESS, 
      [NSNumber numberWithInt:75], 
      FREQUENCY, @"A", TYPE, nil]; 
[array addObject:dict]; 

dict = [NSDictionary dictionaryWithObjectsAndKeys: 
      @"Fjord", NAME, @"Brisbane", ADDRESS, 
      [NSNumber numberWithInt:20], FREQUENCY, 
      @"B", TYPE, nil]; 
[array addObject:dict]; 

Ordinamento descrittori parte utilizzando con il campo di frequenza che è NSNumber:

NSSortDescriptor * frequencyDescriptor = 
    [[[NSSortDescriptor alloc] initWithKey:FREQUENCY 
           ascending:YES] autorelease]; 

id obj; 
NSEnumerator * enumerator = [array objectEnumerator]; 
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj); 

NSArray * descriptors = 
    [NSArray arrayWithObjects:frequencyDescriptor, nil]; 
NSArray * sortedArray = 
    [array sortedArrayUsingDescriptors:descriptors]; 

NSLog(@"\nSorted ..."); 

enumerator = [sortedArray objectEnumerator]; 
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj); 

USCITA - ordinati per campo Frequenza:

2009-12-04 x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; } 
2009-12-04 x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; } 
2009-12-04 x[1] {address = Perth; frequency = 75; name = John; type = A; } 
2009-12-04 x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; } 
2009-12-04 x[1] 
Sorted ... 
2009-12-04 x[1] {address = Brisbane; frequency = 20; name = Fjord; type = B; } 
2009-12-04 x[1] {address = Melbourne; frequency = 50; name = Xentro; type = X; } 
2009-12-04 x[1] {address = Perth; frequency = 75; name = John; type = A; } 
2009-12-04 x[1] {address = Sydney; frequency = 100; name = Alehandro; type = T; } 


Secondo esempio con classe personalizzata e ordinamento su due variabili NSString.

Array per ordinare (vedere Classe A in basso):

NSMutableArray * array = [NSMutableArray array]; 
[array addObject:[[A alloc] initWithFirstName:@"Alehandro" 
            lastName:@"Xentro" 
              age:[NSNumber numberWithInt:40]]]; 
[array addObject:[[A alloc] initWithFirstName:@"John" 
            lastName:@"Smith" 
              age:[NSNumber numberWithInt:30]]]; 
[array addObject:[[A alloc] initWithFirstName:@"John" 
            lastName:@"Smyth" 
              age:[NSNumber numberWithInt:25]]]; 
[array addObject:[[A alloc] initWithFirstName:@"Torro" 
            lastName:@"Ola" 
              age:[NSNumber numberWithInt:45]]]; 
[array addObject:[[A alloc] initWithFirstName:@"Alehandro" 
            lastName:@"Bento" 
              age:[NSNumber numberWithInt:41]]]; 
[array addObject:[[A alloc] initWithFirstName:@"Alehandro" 
            lastName:@"Axel" 
              age:[NSNumber numberWithInt:41]]]; 

La parte di smistamento, sorta su lastName poi firstName:

NSString * LASTNAME = @"lastName"; 
NSString * FIRSTNAME = @"firstName"; 

NSSortDescriptor *lastDescriptor = 
    [[[NSSortDescriptor alloc] 
     initWithKey:LASTNAME 
      ascending:YES 
      selector:@selector(localizedCaseInsensitiveCompare:)] autorelease]; 

NSSortDescriptor *firstDescriptor = 
    [[[NSSortDescriptor alloc] 
     initWithKey:FIRSTNAME 
      ascending:YES 
      selector:@selector(localizedCaseInsensitiveCompare:)] autorelease]; 

NSArray * descriptors = 
    [NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil]; 
NSArray * sortedArray = 
    [array sortedArrayUsingDescriptors:descriptors]; 

Stampa il risultato :

NSLog(@"\nSorted ..."); 

enumerator = [sortedArray objectEnumerator]; 
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj); 

Risultato (prima e dopo l'ordinamento):

2009-12-04 00:52:16.637 x[11375] Alehandro, Xentro, age:40 
2009-12-04 00:52:16.644 x[11375] John, Smith, age:30 
2009-12-04 00:52:16.644 x[11375] John, Smyth, age:25 
2009-12-04 00:52:16.644 x[11375] Torro, Ola, age:45 
2009-12-04 00:52:16.645 x[11375] Alehandro, Bento, age:41 
2009-12-04 00:52:16.645 x[11375] Alehandro, Axel, age:41 
2009-12-04 00:52:16.645 x[11375] 
Sorted ... 
2009-12-04 00:52:16.645 x[11375] Alehandro, Axel, age:41 
2009-12-04 00:52:16.645 x[11375] Alehandro, Bento, age:41 
2009-12-04 00:52:16.645 x[11375] Torro, Ola, age:45 
2009-12-04 00:52:16.645 x[11375] John, Smith, age:30 
2009-12-04 00:52:16.645 x[11375] John, Smyth, age:25 
2009-12-04 00:52:16.645 x[11375] Alehandro, Xentro, age:40 

Classe A estende NSObject - niente di speciale qui:

#import <Foundation/Foundation.h> 

@interface A : NSObject 
{ 
    NSString * firstName; 
    NSString * lastName; 
    NSNumber * age; 
} 

- (id)initWithFirstName:(NSString*)aFirstName 
       lastName:(NSString*)aLastName 
        age:(NSNumber*)anAge; 

-(NSString*)description; 
+(NSString*)action; 

@end 

Implementazione:

#import <Foundation/Foundation.h> 
#import "A.h" 

@implementation A 

- (id)init 
{ 
    return [self initWithFirstName:@"N/A" 
          lastName:@"N/A" 
           age:0]; 
} 

- (id)initWithFirstName:(NSString*)aFirstName 
       lastName:(NSString*)aLastName 
        age:(NSNumber*)anAge 
{ 
    self = [super init]; 
    if (!self) return nil; 

    firstName = [aFirstName copy]; 
    lastName = [aLastName copy]; 
    age = [anAge copy]; 

    return self; 
} 

- (void)dealloc 
{ 
    [firstName release]; 
    [lastName release]; 
    [age release]; 
    [super release]; 
} 

- (NSString *) description 
{ 
    return [NSString stringWithFormat: @"%@, %@, age:%@", 
             firstName, lastName, age]; 
} 
@end 
+10

Grazie per la risposta così dettagliata! – DonnaLea

+1

Grazie mille.Grazie mille :) –

+0

+1, Grazie per la risposta molto descrittiva :) mi ha aiutato molto: D – mAc

Problemi correlati