NSArray 排序总结

NSArray的排序方法有如下:

- (NSArray *)sortedArrayUsingSelector:(SEL)comparator
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0)
- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context

 
 

第一眼看上去,这确实是四个不同的方法,不过原理是一样的,不管是UsingSelector还是UsingComparator还是UsingFunction其实后面的参数

都是要实现比较的方法。下面我们来看看实例。

1、第一种:

NSArray *testAry = @[@"abcd",@"acbd",@"bacd",@"badc",@"bacd",@"cadb"];
testAry = [testAry sortedArrayUsingSelector:@selector(compare:)];

排序前= (
    abcd,
    acbd,
    bacd,
    badc,
    bacd,
    cadb
)
排序后= (
    abcd,
    acbd,
    bacd,
    bacd,
    badc,
    cadb
)

后面这个compare是一个比较方法(升序),可以比较NSNumber和NSString对象(目前我所知就这两种,欢迎各位添加),返回NSComparisonResult

NSComparisonResult是一个枚举,有三个值NSorderdAscending(升序)、NSorderdSame(相同)、NSorderdDescending(降序)

第二种:

NSArray *testAry3 = @[@"222",@"303",@"203",@"32"];
testAry3 = [testAry3 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        if ([obj1 integerValue]<[obj2 integerValue]) {
            return (NSComparisonResult)NSOrderedAscending;
        }
        if ([obj1 integerValue]>[obj2 integerValue]) {
            return (NSComparisonResult)NSOrderedDescending;
        }
        return (NSComparisonResult)NSOrderedSame;
    }];
像这种,我们要比较的是数组中元素的大小,我们就不能用第一种方法了。第一种方法得到的结果是:

排序后= (
    203,
    222,
    303,
    32
)


可以看出来,他并不是比较数字的大小,而是先将第一位排序,然后将第二位排序,以此类推得到上面的结果。而我们是要比较数字的大小,

所以我们可以采用第二种方法。这里我就不详细讲述第二种方法的原理了,第二种方法得到的结果如下:

排序后= (
    32,
    203,
    222,
    303
)

上面的例子是比较简单的排序,但是更多的情况是:我们的数组里面并不是存放一个NSString或者NSNumber。

而是一个对象,我们要根据对象的某一个或多个属性将该数组排序。下面我们用一个demo来讲述另外两种方法。

第三种

首先我们有一个model对象,其实现如下:

.h文件的实现

#import <Foundation/Foundation.h>

@interface model : NSObject

@property (nonatomic)NSString *fristName;
@property (nonatomic)NSString *lastName;
@property (nonatomic)NSString *age;
@property (nonatomic)NSString *weight;

- (id)initWithName:(NSString *)fristName lastname:(NSString *)lastName age:(NSString *)age weight:(NSString *)weight;

@end
.m文件的实现

#import "model.h"

@implementation model

- (id)initWithName:(NSString *)fristName lastname:(NSString *)lastName age:(NSString *)age weight:(NSString *)weight
{
    self = [super init];
    if (self) {
        _fristName = fristName;
        _lastName = lastName;
        _age = age;
        _weight = weight;
    }
    return self;
}

然后我们在ViewController的.m文件中实现如下代码:

说明:创建了两个排序描述(条件),分别是根据fristName和lastName来排序,加入数组的顺序来区分这两个描述的优先级(先加入的优先级高)。

    <pre name="code" class="objc">    model * li = [[model alloc] initWithName:@"li" lastname:@"si" age:@"120" weight:@"100"];
    model * li1 = [[model alloc] initWithName:@"li" lastname:@"simin" age:@"120" weight:@"100"];
    model * zhang = [[model alloc] initWithName:@"zhang" lastname:@"san" age:@"24" weight:@"156"];
    model * liu = [[model alloc] initWithName:@"liu" lastname:@"xi" age:@"38" weight:@"34"];
    model * cao = [[model alloc] initWithName:@"cao" lastname:@"cao" age:@"100" weight:@"203"];
    NSArray *peoples = [NSArray arrayWithObjects:li1,li,zhang,liu,cao, nil];
    for (model *people in peoples) {
        NSLog(@"<span style="font-family: Arial, Helvetica, sans-serif;">排序前people's name =  </span>%@",[NSString stringWithFormat:@"%@ %@",people.fristName,people.lastName]);
    }
    // 创建描述
    NSSortDescriptor *descriptor1 = [[NSSortDescriptor alloc] initWithKey:@"fristName" ascending:YES];
    NSSortDescriptor *descriptor2 = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES];
    // 描述数组
    NSArray *descriptors = [NSArray arrayWithObjects:descriptor1,descriptor2, nil];
    // 根据描述数组进行排序
    peoples = [peoples sortedArrayUsingDescriptors:descriptors];
    for (model *people in peoples) {
        NSLog(@"<span style="font-family: Arial, Helvetica, sans-serif;">排序后people's name =  </span>%@",[NSString stringWithFormat:@"%@ %@",people.fristName,people.lastName]);
    }

 输出结果如下: 
 
排序前people's name = li simin
排序前people's name = li si
排序前people's name = zhang san
排序前people's name = liu xi
排序前people's name = cao cao

排序后people's name = cao cao
排序后people's name = li si
排序后people's name = li simin
排序后people's name = liu xi
排序后people's name = zhang san

第四种:

根据model的age元素来进行排序,weight元素的排序同理:当然我们也可以用第二种方法实现,这里我就不贴了,有兴趣的同学可以自行实现

还是用这个例子,在ViewController中实现如下代码:

    <pre name="code" class="objc">   for (model *people in peoples) {
        NSLog(@"排序前:age = %@",people.age);
    }
    peoples = [peoples sortedArrayUsingFunction:customFunction context:nil];
    for (model *people in peoples) {
        NSLog(@"排序后:age = %@",people.age);
    }

 customFunction是一个自定义的函数,其的实现如下: 
 
    NSInteger customFunction(id obj1, id obj2) {
    model *objj1 = (model *)obj1; model *objj2 = (model *)obj2;
    if ([objj1.age integerValue]<[objj2.age integerValue]) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    if ([objj1.age integerValue]>[objj2.age integerValue]) {
        return (NSComparisonResult)NSOrderedDescending;
    }
    return (NSComparisonResult)NSOrderedSame;
}
输出结果如下:
排序前:age = 100
排序前:age = 120
排序前:age = 120
排序前:age = 38
排序前:age = 24

排序后:age = 24
排序后:age = 38
排序后:age = 100
排序后:age = 120
排序后:age = 120
 
 


有不懂的可以点此下载demo

PS:写博客不多,有错误或者不当的地方,欢迎大家拍砖指正。


你可能感兴趣的:(ios,array,数组排序)