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

学习文章

  • NSArray排序方法讲解
  • “sortedArrayHint” method of NSArray class, what is the purpose of using, and how is it used?
  • Sorting using selectors and functions

简单讲解

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 

@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  

下载源码

下载地址

你可能感兴趣的:(【Objective-C】数组排序方法讲解)