2009-12-04 12 views
28

Tengo una pregunta sobre la clasificación NSMutableArray. Puedo usar el método sortedArrayUsingDescriptors: para ordenar una matriz con objetos.Cómo ordenar NSMutableArray utilizando sortedArrayUsingDescriptors?

Por ejemplo, tengo una NSMutableArray de places donde tengo una frequency (int value) de atributos y quiero ordenar descendente en frequency pero no saben cómo usarlo correctamente.

¿Qué puse como clave en initWithKey?

Mi objetivo 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! Esto es difícil de entender Por favor, babyDeveloper, usa la puntuación (principalmente puntos y comas) en tus preguntas. – pmg

+3

Usted dice que esta "frecuencia" es un valor int, pero su código dice que es un NSString. Por favor, tenga cuidado de expresar sus preguntas con claridad. – Chuck

Respuesta

1

Así es como un aspirante a ordenar 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 "clave" es un método de los objetos (la elementos de su matriz "x") que devuelve lo que desea ordenar. Entonces, en este caso, dijiste que quieres ordenar por la "frecuencia". Entonces, todo lo que tiene que hacer es usar el nombre del método que devuelve la frecuencia, como la clave.

+0

Aunque debería ser de tipo numérico, como 'int' (preferiblemente' unsigned'), 'NSUInteger',' double', o 'NSNumber *'. Con los valores de frecuencia como cadenas, no se ordenarán numéricamente (no sin un comparador personalizado, de todos modos). –

110

ordenar el conjunto de objetos que:

  1. configuración NSSortDescriptor - utilice nombres de las variables como claves para el descriptor de configuración para ordenar más el selector para ser ejecutado en dichas teclas
  2. obtener la matriz de descriptores utilizando NSSortDescriptor que he configurar
  3. tipo matriz basada en los descriptores

He aquí dos ejemplos, uno utilizando NSDictionary y NSString/NSNumber valores que ordenan en NSNumber, el otro que usa clase personalizada con clasificación en dos campos NSString.

Siga Sorting and Filtering NSArray Objects en Cocoa temas de programación para ver más ejemplos y explicación.

Ejemplo:

Esto se hizo en GNUStep debería funcionar igual en Cacao - el código es exactamente la misma - Voy a tratar cuando me siento frente a mi Mac:

primer ejemplo usando NSString y NSNumber valores con la clasificación en NSNumber valor:

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

clasificación de piezas utilizando descriptores con el campo de frecuencia que es 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); 

SALIDA - ordenado por campo Frecuencia:

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 ejemplo con clase personalizada y clasificación en dos variables NSString.

matriz para ordenar (véase la clase A en la 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]]]; 

La parte clasificar, ordenar en lastName continuación primerNombre:

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

imprimir el resultado :

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

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

Resultado (antes y después de la clasificación):

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 

Clase A extiende NSObject - nada especial aquí:

#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 

Implementación:

#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

¡Gracias por una respuesta tan detallada! – DonnaLea

+1

Gracias stefanB.Muchas gracias :) –

+0

+1, gracias por la respuesta muy descriptiva :) me ayudó mucho: D – mAc

Cuestiones relacionadas