iOS NSArray的排序

OC中经常使用的数组排序有三种:数组

sortedArrayUsingSelector(简单排序)
sortedArrayUsingComparator(利用block语法)
sortedArrayUsingDescriptors(高级排序)
复制代码

一: 简单排序(sortedArrayUsingSelector)

若是只是对字符串进行简单的排序, 能够利用sortedArrayUsingSelector:方法就能够了,代码以下:bash

NSArray *array = @[@"d",@"e",@"a",@"c",@"m",@"h"];
NSLog(@"array = %@",[array sortedArrayUsingSelector:@selector(compare:)]);
//输出:(a,c,d,e,h,m)
复制代码

固然, 除了利用字符串自带的compare:方法, 也能够本身写compare:方法, 进行对象的比较; 以下:函数

首先是新建Person类, .h文件以下:测试

@interface Person : NSObject
//年龄
@property (nonatomic, assign) int age;
//名字
@property (nonatomic, strong) NSString *name;

//直接实现静态方法, 获取带有name和age的Person对象
+ (Person *)personWithAge:(int)age withName:(NSString *)name;

//自定义排序方法
- (NSComparisonResult)comparePerson:(Person *)person;
@end
复制代码

.m文件以下:ui

#import "Person.h"

@implementation Person

//直接实现静态方法, 获取带有name和age的Person对象
+ (Person *)personWithAge:(int)age withName:(NSString *)name {
    Person *person = [[Person alloc] init];
    person.age = age;
    person.name = name;
    return person;
}

//自定义排序方法
- (NSComparisonResult)comparePerson:(Person *)person {    
    //默认按年龄排序
    //注意: 基本数据类型要进行数据转换
    NSComparisonResult result = [[NSNumber numberWithInt:self.age] compare:[NSNumber numberWithInt:person.age]];
    //若是年龄同样, 就按照名字排序
    if (result == NSOrderedSame) {
        result = [self.name compare:person.name];
    }
    return  result;
}

@end
复制代码

主函数代码:atom

Person *p1 = [Person personWithAge:23 withName:@"zhaoyi"];
Person *p2 = [Person personWithAge:21 withName:@"qianer"];
Person *p3 = [Person personWithAge:24 withName:@"zhangsan"];
Person *p4 = [Person personWithAge:24 withName:@"lisi"];
Person *p5 = [Person personWithAge:20 withName:@"wangwu"];
    
NSArray *array = [NSArray arrayWithObjects:p1, p2, p3, p4, p5, nil];
NSArray<Person *> *sortedArray = [array sortedArrayUsingSelector: @selector(comparePerson:)];
[sortedArray enumerateObjectsUsingBlock:^(Person *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"排序后的年龄: %d, 名字: %@",obj.age, obj.name);
}];

输出:
排序后的年龄: 20, 名字: wangwu
排序后的年龄: 21, 名字: qianer
排序后的年龄: 23, 名字: zhaoyi
排序后的年龄: 24, 名字: lisi
排序后的年龄: 24, 名字: zhangsan
复制代码

二: 利用block语法(sortedArrayUsingComparator)

苹果官方提供了block语法, 比较方便. 其中数组排序能够用sortedArrayUsingComparator:方法, 代码以下:spa

NSArray *array = @[@"cda", @"efj", @"iqw", @"adb", @"lcd", @"hil"];
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
    //这里的代码能够参照上面compare: 默认的排序方法, 也能够把自定义的方法写在这里, 给对象排序
    NSComparisonResult result = [obj1 compare:obj2];
    return result;
}];
NSLog(@"排序后数组: %@",sortedArray);
    
输出:(adb, cda, efj, hil, iqw, lcd)
复制代码

三:高级排序:

若是是这样一种状况呢? Person类里有另一个类的变量, 好比说Person类除了name, age变量, 还有一辆车Car类型, Car类里有个name属性. 对Person对象进行排序, 有这样的要求:按照Car的name排序, 若是是同一辆车, 也就是Car的name相同, 那么再按照年龄进行排序, 若是年龄也相同, 最后按照Person的name进行排序..net

上面这种状况, 就要使用第三种方法, 利用排序描述器了.代码以下: 首先写个Car类, .h文件以下:code

@interface Car : NSObject
/** 汽车名字 */
@property (nonatomic, strong) NSString *name;

+ (Car *)initWithName:(NSString *)name;
@end
复制代码

.m文件以下:orm

#import "Car.h"

@implementation Car

+ (Car *)initWithName:(NSString *)name {
    Car *car = [[Car alloc] init];
    car.name = name;
    return car;
}

@end

复制代码

Person类的.h文件, 代码以下:

@interface Person : NSObject
//年龄
@property (nonatomic, assign) int age;
//名字
@property (nonatomic, strong) NSString *name;
//汽车
@property (nonatomic, strong) Car *car;


+ (Person *)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car;
@end
复制代码

Person类的.m文件, 代码以下:

#import "Person.h"

@implementation Person

//直接实现静态方法, 获取带有name和age的Person对象
+ (Person *)personWithAge:(int)age withName:(NSString *)name {
    Person *person = [[Person alloc] init];
    person.age = age;
    person.name = name;
    return person;
}

+ (Person *)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car {
    Person *person = [[Person alloc] init];
    person.age = age;
    person.name = name;
    person.car = car;
    return person;
}

//这里重写description方法, 用于最后测试排序结果显示
- (NSString *)description {
    return [NSString stringWithFormat:@"age is %d, name is %@, car.name is %@",_age, _name, _car.name];
}

@end
复制代码

主函数代码以下:

Car *car1 = [Car initWithName:@"Audio"];
Car *car2 = [Car initWithName:@"Rolls-Royce"];
Car *car3 = [Car initWithName:@"BMW"];
    
Person *p1 = [Person personWithAge:23 withName:@"zhaoyi" withCar:car2];
Person *p2 = [Person personWithAge:21 withName:@"qianer" withCar:car1];
Person *p3 = [Person personWithAge:24 withName:@"zhangsan" withCar:car1];
Person *p4 = [Person personWithAge:24 withName:@"lisi" withCar:car3];
Person *p5 = [Person personWithAge:20 withName:@"wangwu" withCar:car2];
    
//加入数组
NSArray *array = [NSArray arrayWithObjects:p1, p2, p3, p4, p5, nil];
    
//构建排序描述器
NSSortDescriptor *carNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"car.name" ascending:YES];
NSSortDescriptor *personNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor *personAgeDesc = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
    
//把排序描述器放进数组里, 放入的顺序就是你想要排序的排序
//这里的排序是: 首先按照年龄排序, 而后是车的名字, 最后是按照人的名字
NSArray *descriptorArray = [NSArray arrayWithObjects:personAgeDesc, carNameDesc, personNameDesc, nil];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:descriptorArray];
    
[sortedArray enumerateObjectsUsingBlock:^(Person *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    NSLog(@"排序后的年龄: %d, 车的名字: %@, 名字: %@",obj.age, obj.car.name, obj.name);
}];
   
输出:
排序后的年龄: 20, 车的名字: Rolls-Royce, 名字: wangwu
排序后的年龄: 21, 车的名字: Audio, 名字: qianer
排序后的年龄: 23, 车的名字: Rolls-Royce, 名字: zhaoyi
排序后的年龄: 24, 车的名字: Audio, 名字: zhangsan
排序后的年龄: 24, 车的名字: BMW, 名字: lisi

从结果能够看出, 先按照age排序, 若是age相同; 按照car的名字排序; 若是car的名字相同, 再按照name排序;
复制代码

原文:my.oschina.net/pengloo53/b…

相关文章
相关标签/搜索