如何使用sortedArrayUsingDescriptors对NSMutableArray进行排序?

时间:2009-12-04 00:16:22

标签: objective-c cocoa sorting nsmutablearray

我对排序NSMutableArray有疑问。我可以使用sortedArrayUsingDescriptors:方法对数组进行排序。

例如,我有NSMutableArray places我有一个属性frequency(int值),我想在frequency上降序排序,但我不是知道如何正确使用它。

我在initWithKey中将哪些内容作为密钥?

我的对象place包含:

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

3 个答案:

答案 0 :(得分:111)

要对您的对象数组进行排序:

  1. setup NSSortDescriptor - 使用变量名作为设置排序描述符的键以及要在这些键上执行的选择器
  2. 使用您已设置的NSSortDescriptor获取描述符数组
  3. 根据这些描述符对数组进行排序
  4. 以下是两个示例,一个使用NSDictionary上的NSString/NSNumberNSNumber值排序,另一个使用自定义类在两个NSString字段上进行排序。

    在Cocoa编程主题中关注Sorting and Filtering NSArray Objects以查看更多示例和说明。

    示例

    这是在GNUStep上完成的,它应该在Cocoa上运行相同 - 代码完全一样 - 当我坐在我的Mac前面时我会尝试:

    使用NSStringNSNumber值并在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];
    

    使用带有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);
    

    输出 - 按频率字段排序:

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


    自定义类和第二个NSString变量排序的第二个示例。

    要排序的数组(请参阅底部的课程A):

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

    排序部分,在lastName上排序,然后按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];
    

    打印结果:

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

    结果(排序前后):

    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
    

    班级A延伸NSObject - 这里没什么特别的:

    #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
    

    实现:

    #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
    

答案 1 :(得分:2)

“key”是对象的方法(数组“x”的元素),它返回要排序的对象。所以在这种情况下,你说你想按“频率”排序。然后,您所要做的就是使用返回频率的方法的名称作为密钥。

答案 2 :(得分:1)

以下是对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