OC中經常使用的數組排序有三種:數組
sortedArrayUsingSelector(簡單排序)
sortedArrayUsingComparator(利用block語法)
sortedArrayUsingDescriptors(高級排序)
複製代碼
若是隻是對字符串進行簡單的排序, 能夠利用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:方法, 代碼以下: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排序;
複製代碼