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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1844031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 22:35:01  来源:igfitidea点击:

How to sort NSMutableArray using sortedArrayUsingDescriptors?

objective-ccocoasortingnsmutablearray

提问by babyDeveloper

I have a question about sorting NSMutableArray. I can use sortedArrayUsingDescriptors:method to sort an array with objects.

我有一个关于排序的问题NSMutableArray。我可以使用sortedArrayUsingDescriptors:方法对包含对象的数组进行排序。

For example I have an NSMutableArrayof placeswhere I have an attribute frequency(int value) and I want to sort descending on frequencybut I don't know how to use it correctly.

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

What do I put as a key in initWithKey?

我把什么作为钥匙initWithKey

My object placecontains:

我的对象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];

回答by stefanB

To sort your array of objects you:

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

  1. setup NSSortDescriptor- use names of your variables as keys to setup descriptor for sorting plus the selector to be executed on those keys
  2. get the array of descriptors using NSSortDescriptorthat you've setup
  3. sort your array based on those descriptors
  1. setup NSSortDescriptor- 使用变量的名称作为键来设置用于排序的描述符以及要在这些键上执行的选择器
  2. 使用NSSortDescriptor您设置的描述符获取描述符数组
  3. 根据这些描述符对数组进行排序

Here are two examples, one using NSDictionaryand NSString/NSNumbervalues sorting on NSNumber, the other one using custom class with sorting on two NSStringfields.

这里有两个例子,一个使用NSDictionaryNSString/NSNumber值排序NSNumber,另一个使用自定义类对两个NSString字段进行排序。

Follow Sorting and Filtering NSArray Objectsin Cocoa programming topics to see more examples and explanation.

按照Cocoa 编程主题中的排序和过滤 NSArray 对象查看更多示例和说明。

Example:

示例

This was done on GNUStep it should work the same on Cocoa - the code is exactly the same - I'll try when I sit in front of my Mac:

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

First example using NSStringand NSNumbervalues with sorting on NSNumbervalue:

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


Sorting part using descriptors with the Frequency field which is NSNumber:

使用带有频率字段的描述符对部分进行排序,该字段是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 - sorted by Frequency field:

输出 - 按频率字段排序:

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




Second example with custom class and sorting on two NSStringvariables.

带有自定义类和对两个NSString变量进行排序的第二个示例。

Array to sort (see class Aat the bottom):

要排序的数组(请参阅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]]];


The sorting part, sort on lastName then 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];


Print the result:

打印结果:

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

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


Result (before and after 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

Class Aextends NSObject- nothing special here:

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

Implementation:

执行:

#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

回答by newacct

The "key" is a method of your objects (the elements of your array "x") that returns the thing you want to sort by. So in this case, you said that you want to sort by the "frequency". Then all you have to do is use the name of the method that returns the frequency, as the key.

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

回答by ennuikiller

Here's how a would sort an NSMutableArray:

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