Como classificar NSMutableArray usando sortedArrayUsingDescriptors?

Eu tenho uma pergunta sobre a sorting de NSMutableArray . Eu posso usar o método sortedArrayUsingDescriptors: para classificar uma matriz com objects.

Por exemplo, eu tenho um NSMutableArray de places onde eu tenho uma frequency atributo (int valor) e eu quero ordenar decrescente na frequency mas eu não sei como usá-lo corretamente.

O que eu coloco como chave no initWithKey ?

Meu place object contém:

 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]; 

Para classificar sua matriz de objects você:

  1. setup NSSortDescriptor – use nomes de suas variables ​​como chaves para configurar o descritor para sorting mais o seletor a ser executado nessas chaves
  2. obter a matriz de descritores usando o NSSortDescriptor que você configurou
  3. ordenar sua matriz com base nesses descritores

Aqui estão dois exemplos, um usando valores NSDictionary e NSString/NSNumber classificando em NSNumber , o outro usando classs personalizadas com sorting em dois campos NSString .

Siga Classificando e Filtrando os Objetos NSArray nos tópicos de programação Cocoa para ver mais exemplos e explicações.

Exemplo :

Isso foi feito no GNUStep, ele deve funcionar da mesma forma no Cocoa – o código é exatamente o mesmo – vou tentar quando eu estiver sentado na frente do meu Mac:

Primeiro exemplo usando valores NSString e NSNumber com sorting no valor NSNumber :

 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]; 

Classificando parte usando descritores com o campo Frequency que é 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); 

OUTPUT – classificado por campo de frequência:

 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; } 


Segundo exemplo com class personalizada e sorting em duas variables NSString .

Matriz para ordenar (veja a class A na parte inferior):

 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]]]; 

A parte de sorting, classifique lastName e 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]; 

Imprima o resultado:

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

Resultado (antes e depois da sorting):

 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 – nada de especial aqui:

 #import  @interface A : NSObject { NSString * firstName; NSString * lastName; NSNumber * age; } - (id)initWithFirstName:(NSString*)aFirstName lastName:(NSString*)aLastName age:(NSNumber*)anAge; -(NSString* )description; +(NSString*)action; @end 

Implementação:

 #import  #import "Ah" @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 

A “chave” é um método dos seus objects (os elementos da sua matriz “x”) que retorna a coisa pela qual você deseja classificar. Então, neste caso, você disse que você quer classificar pela “frequência”. Então tudo que você precisa fazer é usar o nome do método que retorna a freqüência, como a chave.

Veja como um classificaria um 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