iOS 数组排序

Pre:很多文章对于SEL排序讲解太过含糊,特写此文讲述清楚。

官方提供了几个api进行数组排序操作,开发者只需提供两个元素的比较规则,而无需关心元素在数组中是如何移动直至全部有序化。

首先看下面的2个定义。对typedef的更多使用参考这里。

1.定义NSComparisonResult类型返回值
typedef NS_ENUM(NSInteger, NSComparisonResult)
{
    //代表升续
    NSOrderedAscending = -1L,    
    //代表相同
    NSOrderedSame,
    //代表降序                      
    NSOrderedDescending        
};

2.定义NSComparator block类型返回值
 typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

注意:NSArray的排序方法是生成一个排好序的新数组。NSMutableArray的排序可以直接对该数组进行排序sortUsingComparator:,也可以生成新数组sortedArrayUsingComparator: ,而原数组不变。

1.使用block进行排序(推荐使用)

NSMutableArray *arr = [NSMutableArray array];

[arr addObject:@2];
[arr addObject:@1];
[arr addObject:@5];
[arr addObject:@3];
[arr addObject:@4];

//此方法是直接对arr排序,若要生成新数组排序则调用sortedArrayUsingComparator:
//若明确知道数组中元素的类型,也可以直接将id改为某确定类型
[arr sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2)
{
    //此处的规则含义为:若前一元素比后一元素小,则返回降序(即后一元素在前,为从大到小排列)
    if ([obj1 integerValue] < [obj2 integerValue])
    {
        return NSOrderedDescending;
    }
    else
    {
        return NSOrderedAscending;
    }
}];

排序结果为 5,4,3,2,1

2.使用SEL排序

NSMutableArray *arr = [NSMutableArray array];

for (NSInteger i = 0; i < 5; i++)
{
    Student *stu = [Student new];
    //生成10-20的随机数
    stu.age = arc4random_uniform(10) + 10;
    [arr addObject:stu];
}

//此处的sel应该理解为对数组中A对象调用自己的sel,传入值为B对象,同时返回值为NSComparisonResult
[arr sortUsingSelector:@selector(compareWithStu:)];

Student对象必须有一个自定义比较方法进行排序。此方法必须有一个传入值(传入Student对象用以比对)和一个返回值(NSComparisonResult类型)。

Student具体如下

.h
@interface Student : NSObject
@property (assign, nonatomic) NSInteger age;
/** 排序规则*/
- (NSComparisonResult)compareWithStu:(Student *)stu;
@end

.m
@implementation Student
/** 排序规则*/
- (NSComparisonResult)compareWithStu:(Student *)stu
{
    //按照升续排列
    if (self.age > stu.age)
    {
        return NSOrderedDescending;
    }
    else if (self.age == stu.age)
    {
        return NSOrderedSame;
    }
    else
    {
       return NSOrderedAscending;
    }
}
@end

某次运行结果为
(
    "age -> 10",
    "age -> 12",
    "age -> 12",
    "age -> 18",
    "age -> 19"
)

写在最后:

1.排序是一个消耗性能的操作,应尽量避免频繁排序。
2.对于已经排好序的数组再排序可以使用sortedArrayHint进行性能优化。在排序进阶篇会补上相关内容。
3.对于数组中对象是NSString的排序推荐使用第二种方案,因为NSString已经有了排序方案如compare:方法已经是按照升序排列了。关于NSString的排序内容很多,另一篇填此坑。
4.对于排序还有一些高级用法,会在下一遍详细说明。

你可能感兴趣的:(iOS 数组排序)