前言:
今天看到同事写的一段排序代码,我第一反应是如果是当前这种需求,我不会这样写,同时,我又在想他这样写是不是有别的意图,这种写法有什么好处,还有没有其他方法可以实现,于是就有了这篇笔记
//按字母顺序排序 - 升序
//同事写法
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) 如果后面的selector为compare: 则默认升序排序,适用于数组内元素为简单类型的排序,如:字符串、基本数字类型。如果是字符串类型,则会从第一个字符开始依次比较;数字类型则直接比较大小,比较简单,这里不再演示;
NSArray *arr1 = @[@"lucy",@"2tom",@"lykk",@"john",@"marry"];
//升序
NSArray *result1 = [arr1 sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"升序 = %@",result1);
//当然先这样实现了升序,但你想要降序,怎么办?
//倒序输出 -> 得到降序数组
result1 = [[result1 reverseObjectEnumerator] allObjects];
NSLog(@"降序 = %@",result1);
(2) 如果后面的selector为自定义方法,适用于复杂对象的排序,这里我定义一个学生对象,个人觉得该方法稍麻烦,实际开发中使用不多。
首先需要去对象的.h 文件去声明排序方法,并去.m文件目录下实现下。
Student.h Student.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) { }];
这是Xcode4 之后出的一个比较好用的一个排序方法,不像自定义排序方法那样麻烦,个人建议在开发中复杂类型的排序用这种方法。
(1)对简单类型进行排序
(2)对复杂对象进行排序
排序结果- 高级排序 :按描述进行排序 - 制定一套排序规则
总结:
上述简单的介绍了几种在OC中排序的方法,有纰漏之处还请大家指出,后续有时间再补充其他排序方法;当然使用冒泡排序,或者选择排序也可以实现上述排序,这里不再代码演示。
网友评论