【Objective-C】数组排序方法讲解

学习文章

简单讲解

NSArray的排序方法:

- sortedArrayUsingFunction:context:    
– sortedArrayUsingFunction:context:hint:
– sortedArrayUsingDescriptors:  
– sortedArrayUsingSelector:  
- sortedArrayUsingComparator:   
- sortedArrayWithOptions:usingComparator: 

以上方法可以分为四类,Function,Descriptor,Selector,Comparator,最简单易用的应该是Comparator,用一个Block非常方便的解决大多数排序,强烈推荐,其他方法稍微麻烦一些,大家了解一下.下面我们分类讲解一下.

Function排序

首先,自己按照参数要求写排序方法,如:

NSInteger intSort(id num1, id num2, void *context) {
    
    int v1 = [num1 intValue];
    int v2 = [num2 intValue];
    
    if (v1 < v2) {
    
        return NSOrderedAscending;
        
    } else if (v1 > v2) {
    
       return NSOrderedDescending;
        
    } else {
    
        return NSOrderedSame;
    }
}  

然后调用即可

NSArray *numberArray = @[@2, @4, @12, @1, @9];  
NSArray *funcitonSortedArray = [numberArray sortedArrayUsingFunction:intSort context:NULL];
NSLog(@" funcitonSortedArray = %@",funcitonSortedArray);  

打印信息:

funcitonSortedArray = (
    1,
    2,
    4,
    9,
    12
)  

Function排序还有一个方法 – sortedArrayUsingFunction:context:hint:,这个方法用在这样的情景:

假设你有一个经常要排序的大数组,即使轻微的改变(比如添加或删除一个元素),也需要重新对数组排序,这样排序成本很高.这时,我们就可以用此方法.

首先,[anArray sortedArrayHint],此方法应该被已排序好的数组调用,来获得一个私有的data来加速轻微改变的数组的排序.

下面是简单用法,由于数组不够大,所以,体现不出此方法的优势.

NSInteger alphabeticSort(id string1, id string2, void *reverse)
{
    if (*(BOOL *)reverse == YES) {
        
        return [string2 localizedCaseInsensitiveCompare:string1];
    }
    
    return [string1 localizedCaseInsensitiveCompare:string2];
}  
  
- (void)hintFunctionDemo {

    NSMutableArray *anArray =
    [NSMutableArray arrayWithObjects:@"aa", @"ab", @"ac", @"ad", @"ae", @"af", @"ag",
     @"ah", @"ai", @"aj", @"ak", @"al", @"am", @"an", @"ao", @"ap", @"aq", @"ar", @"as", @"at",
     @"au", @"av", @"aw", @"ax", @"ay", @"az", @"ba", @"bb", @"bc", @"bd", @"bf", @"bg", @"bh",
     @"bi", @"bj", @"bk", @"bl", @"bm", @"bn", @"bo", @"bp", @"bq", @"br", @"bs", @"bt", @"bu",
     @"bv", @"bw", @"bx", @"by", @"bz", @"ca", @"cb", @"cc", @"cd", @"ce", @"cf", @"cg", @"ch",
     @"ci", @"cj", @"ck", @"cl", @"cm", @"cn", @"co", @"cp", @"cq", @"cr", @"cs", @"ct", @"cu",
     @"cv", @"cw", @"cx", @"cy", @"cz", nil];
    
    // note: anArray is sorted
    NSData *sortedArrayHint = [anArray sortedArrayHint];
    
    [anArray insertObject:@"be" atIndex:5];
    
    // sort with a hint
    BOOL reverseSort = NO;
    NSArray *sortedArray = [anArray sortedArrayUsingFunction:alphabeticSort
                                                     context:&reverseSort
                                                        hint:sortedArrayHint];
    
    NSLog(@"hintFunctionSortedArray = %@",sortedArray);
} 

打印信息:

hintFunctionSortedArray = (
    aa,
    ab,
    ac,
    ad,
    ae,
    af,
    ag,
    ah,
    ai,
    aj,
    ak,
    al,
    am,
    an,
    ao,
    ap,
    aq,
    ar,
    as,
    at,
    au,
    av,
    aw,
    ax,
    ay,
    az,
    ba,
    bb,
    bc,
    bd,
    be,
    bf,
    bg,
    bh,
    bi,
    bj,
    bk,
    bl,
    bm,
    bn,
    bo,
    bp,
    bq,
    br,
    bs,
    bt,
    bu,
    bv,
    bw,
    bx,
    by,
    bz,
    ca,
    cb,
    cc,
    cd,
    ce,
    cf,
    cg,
    ch,
    ci,
    cj,
    ck,
    cl,
    cm,
    cn,
    co,
    cp,
    cq,
    cr,
    cs,
    ct,
    cu,
    cv,
    cw,
    cx,
    cy,
    cz
)

Selector排序

NSString,NSNumber都有和排序相关的方法,如NSString有


 - (NSComparisonResult)compare:(NSString *)string;
 - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
 - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
 - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(nullable id)locale;
 - (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
 - (NSComparisonResult)localizedCompare:(NSString *)string;
 - (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;  

我们可以直接利用这些方法来排序


NSArray *alphabeticArray  = @[@"b", @"a", @"x", @"o", @"g", @"o"];   
NSLog(@"%@",selectorSortedArray);  

打印信息:

selectorSortedArray = (
    a,
    b,
    g,
    o,
    o,
    x
)

Descriptor排序

用NSSortDescriptor,它是一个获取keyPath的工具,它能根据keyPath进行排序

NSArray *modelArray = @[[Model name:@"LiuDaShuai"  age:@26 height:@171],
                        [Model name:@"XiaoQiu"     age:@27 height:@170],
                        [Model name:@"HaoQuShi"    age:@28 height:@172],
                        [Model name:@"JunGang"     age:@24 height:@171],
                        [Model name:@"KongMing"    age:@30 height:@175],
                        [Model name:@"GaoFuShuai"  age:@22 height:@180]];  

NSSortDescriptor *sortDescriptor        = [[NSSortDescriptor alloc] initWithKey:@"m_age" ascending:YES];
    NSArray          *sortDescriptors       = [NSArray arrayWithObject:sortDescriptor];
    NSArray          *descriptorSortedArray = [modelArray sortedArrayUsingDescriptors:sortDescriptors];   
   
[descriptorSortedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        Model *tmp = obj;
        NSLog(@"descriptorSortedArray model = %@", tmp.m_name);
    }];

打印信息

descriptorSortedArray model = GaoFuShuai
descriptorSortedArray model = JunGang
descriptorSortedArray model = LiuDaShuai
descriptorSortedArray model = XiaoQiu
descriptorSortedArray model = HaoQuShi
descriptorSortedArray model = KongMing  

可以将上面的步骤封装成类目,便于使用:

NSArray+DescriptorSort.h

#import <Foundation/Foundation.h>

@interface NSArray (DescriptorSort)

- (NSArray*)sortedWithKeyPath: (NSString*)keyPath ascending: (BOOL)ascending;

@end  

NSArray+DescriptorSort.m

#import "NSArray+DescriptorSort.h"

@implementation NSArray (DescriptorSort)

- (NSArray*)sortedWithKeyPath: (NSString*)keyPath ascending: (BOOL)ascending {

    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc]initWithKey:keyPath ascending:ascending];
    
    return [self sortedArrayUsingDescriptors:@[descriptor]];
}

@end  

Comparator排序

最简单易用,强烈推荐

NSArray *modelArray = @[[Model name:@"LiuDaShuai"  age:@26 height:@171],
                        [Model name:@"XiaoQiu"     age:@27 height:@170],
                        [Model name:@"HaoQuShi"    age:@28 height:@172],
                        [Model name:@"JunGang"     age:@24 height:@171],
                        [Model name:@"KongMing"    age:@30 height:@175],
                        [Model name:@"GaoFuShuai"  age:@22 height:@180]];   

NSArray *comparatorSortedArray = [modelArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        
        Model *model1 = obj1;
        Model *model2 = obj2;
        
        return [model1.m_name compare:model2.m_name];
    }];
    
    // 打印排序信息
    [comparatorSortedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        Model *tmp = obj;
        NSLog(@"comparatorSortedArray model = %@", tmp.m_name);
    }];
  

打印信息:

comparatorSortedArray model = GaoFuShuai
comparatorSortedArray model = HaoQuShi
comparatorSortedArray model = JunGang
comparatorSortedArray model = KongMing
comparatorSortedArray model = LiuDaShuai
comparatorSortedArray model = XiaoQiu  

下载源码

下载地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341

推荐阅读更多精彩内容