J'ai une question sur le tri NSMutableArray
. Je peux utiliser sortedArrayUsingDescriptors:
méthode pour trier un tableau avec des objets.
Par exemple, j'ai un NSMutableArray
de places
où j'ai un attribut frequency
(valeur int) et je veux trier par ordre décroissant sur frequency
mais je ne ' Je ne sais pas comment l’utiliser correctement.
Que dois-je mettre comme clé dans initWithKey
?
Mon objet place
contient:
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];
Pour trier votre tableau d'objets, vous:
NSSortDescriptor
- utilisez les noms de vos variables comme clés pour configurer le descripteur de tri ainsi que le sélecteur à exécuter sur ces clésNSSortDescriptor
que vous avez configuréVoici deux exemples, l'un utilisant NSDictionary
et NSString/NSNumber
valeurs triant sur NSNumber
, l'autre utilisant une classe personnalisée avec tri sur deux NSString
champs.
Suivez Tri et filtrage des objets NSArray dans les rubriques de programmation Cocoa pour voir plus d'exemples et d'explications.
Exemple :
Cela a été fait sur GNUStep cela devrait fonctionner de la même manière sur Cocoa - le code est exactement le même - je vais essayer quand je serai assis devant mon Mac:
Premier exemple utilisant des valeurs NSString
et NSNumber
avec tri sur NSNumber
valeur:
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];
Tri de la partie à l'aide de descripteurs avec le champ Fréquence qui est 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);
SORTIE - trié par champ Fréquence:
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; }
Deuxième exemple avec classe personnalisée et tri sur deux variables NSString
.
Tableau à trier (voir classe A
en bas):
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 partie de tri, triez par nom puis par prénom:
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];
Imprimez le résultat:
NSLog(@"\nSorted ...");
enumerator = [sortedArray objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);
Résultat (avant et après tri):
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
étend NSObject
- rien de spécial ici:
#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
La mise en oeuvre:
#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
La "clé" est une méthode de vos objets (les éléments de votre tableau "x") qui renvoie la chose que vous souhaitez trier. Donc dans ce cas, vous avez dit que vous vouliez trier par "fréquence". Il vous suffit ensuite d'utiliser le nom de la méthode qui renvoie la fréquence, comme clé.
Voici comment un trierait 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