前言:
今天看到同事写的一段排序代码,我第一反应是如果是当前这种需求,我不会这样写,同时,我又在想他这样写是不是有别的意图,这种写法有什么好处,还有没有其他方法可以实现,于是就有了这篇文章
//按字母顺序排序 - 升序
//同事写法
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2];
}];
//我会这样写 - 相信大多数人都会这样写
NSArray *sortedArray = [keys sortedArrayUsingSelector:@selector(compare:)];
正文:
首先确定你要比较的元素是同一类型,不然程序会crash
;
这里只讲不可变数组的排序,可变数组的排序原理一样,方法名不同而已;
1. 先来介绍一下- (NSArray *)sortedArrayUsingSelector:(SEL)comparator
; 返回一个数组,并通过给定的比较方法来接收排序后的元素
1.1 如果后面的selector
为compare:
则默认升序排序,适用于数组内元素为简单类型的排序,如:字符串、基本数字类型。如果是字符串类型,则会从第一个字符开始依次比较;数字类型则直接比较大小,比较简单,这里不再演示;
NSArray *arr1 = @[@"lucy",@"2tom",@"lykk",@"john",@"marry"];
//升序
NSArray *result1 = [arr1 sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"升序 = %@",result1);
//当然先这样实现了升序,但你想要降序,怎么办?
//倒序输出 -> 得到降序数组
result1 = [[result1 reverseObjectEnumerator] allObjects];
NSLog(@"降序 = %@",result1);
1.2 如果后面的selector
为自定义方法,适用于复杂对象的排序,这里我定义一个学生对象,个人觉得该方法稍麻烦,实际开发中使用不多。
首先需要去对象的.h
文件去声明排序方法,并去.m
文件目录下实现下。
注意:这里还有一种情况,就是比较的这两个元素相等时,这个排序的顺序是怎样的?
我修改了上面stu
队列的两个地方:
① 将stu4
的age
更改为20
;
② 改变stu4
在原数组中的位置,下标由3
变为1
;
我们再来看一下按age
排的结果:
我们可以看到
Tom
和john
的age
一样,但是Tom
排在了john
的前面,原因是Tom
在原始队列中的位置比john
靠前。但是Tom
原来的下标为1
,现在变成了2
,可见指定排序规则的优先级最高,如果出现比较元素相等的情况,系统才会默认比较原始下标。这让我想到了上学时班里的成绩表,明明我和好几个同学的成绩一样,可可为什么我排在了最后面?:
① 当成绩一样之后,排名软件没做处理,默认根据原始队列下标排序;
② 也可能增加一条比较规则,再根据姓名比较/根据学号比较;
③ 也可能会出现姓名一样的情况,这时候再定义一条规则,根据学号来比较(其实这里比较完成绩后再根据学号比较好,学号一般在一个学校里是唯一的)代码中具体怎么加规则,下面会提到
2. 接下来我们来介绍一下我同事使用的那种排序方法sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { }];
这是Xcode 4
之后出的一个比较好用的一个排序方法,不像自定义排序方法那样麻烦,个人建议在开发中复杂类型的排序用这种方法。
2.1 对简单类型进行排序
2.2 对复杂对象进行排序
3. 高级排序:按描述进行排序(制定一套排序规则 )
4. 总结:
上述简单的介绍了几种在OC
中排序的方法,有纰漏之处还请大家指出,后续有时间再补充其他排序方法;当然使用冒泡排序/选择排序等也可以实现上述排序,这里不再代码演示。