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…

相關文章
相關標籤/搜索