A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 路默” 中级黑马   /  2014-4-19 04:34  /  23259 人查看  /  15 人回复  /   4 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 路默” 于 2014-4-19 14:12 编辑

在OC中,把几个对象创建为一个数组,怎样才能对对象内的元素进行比较排序->OC方法

评分

参与人数 1技术分 +1 收起 理由
jing迪 + 1

查看全部评分

15 个回复

倒序浏览
本帖最后由 董月峰 于 2014-4-19 07:51 编辑

转自本人博客http://850361034.blog.163.com/blog/static/32803809201436111445914/
  1. 大体上,OC中常用的数组排序有以下几种方法:sortedArrayUsingSelector:;sortedArrayUsingComparator:;sortedArrayUsingDescriptors:。


  2. 1、简单排序(sortedArrayUsingSelector:)
  3. 如果只是对字符串的排序,可以利用sortedArrayUsingSelector:方法就可以了,代码如下

  4. //简单排序
  5. void sortArray1(){
  6.     NSArray *array = [NSArray arrayWithObjects:@"abc",@"456",@"123",@"789",@"ef", nil];
  7.     NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)];
  8.     NSLog(@"排序后:%@",sortedArray);
  9. }
  10. 当然,除了利用字符串自带的compare:方法,也可以自己写compare:方法,进行对象的比较;如下:

  11. 首先是新建了Person类,实现方法如下(头文件就省了):

  12. #import "Person.h"
  13. @implementation Person

  14. //直接实现静态方法,获取带有name和age的Person对象
  15. +(Person *)personWithAge:(int) age withName:(NSString *)name{
  16.     Person *person = [[Person alloc] init];
  17.     person.age = age;
  18.     person.name = name;
  19.     return person;
  20. }

  21. //自定义排序方法
  22. -(NSComparisonResult)comparePerson:(Person *)person{
  23.   //默认按年龄排序
  24.     NSComparisonResult result = [[NSNumber numberWithInt:person.age] compare:[NSNumber numberWithInt:self.age]];//注意:基本数据类型要进行数据转换
  25.   //如果年龄一样,就按照名字排序
  26.     if (result == NSOrderedSame) {
  27.         result = [self.name compare:person.name];
  28.     }
  29.     return result;
  30. }

  31. @end
  32. 主函数代码如下:

  33. void sortArray2(){
  34.     Person *p1 = [Person personWithAge:23 withName:@"zhangsan"];
  35.     Person *p2 = [Person personWithAge:21 withName:@"lisi"];
  36.     Person *p3 = [Person personWithAge:24 withName:@"wangwu"];
  37.     Person *p4 = [Person personWithAge:24 withName:@"liwu"];
  38.     Person *p5 = [Person personWithAge:20 withName:@"liwu"];
  39.     NSArray *array = [NSArray arrayWithObjects:p1,p2,p3,p4,p5, nil];
  40.     NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(comparePerson:)];
  41.     NSLog(@"排序后:%@",sortedArray);
  42. }

  43. 2、利用block语法(sortedArrayUsingComparator:)
  44. 苹果官方提供了block语法,比较方便。其中数组排序可以用sortedArrayUsingComparator:方法,代码如下:

  45. void sortArray3(){
  46.     NSArray *array = [NSArray arrayWithObjects:@"1bc",@"4b6",@"123",@"789",@"3ef", nil];
  47.     NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

  48.    //这里的代码可以参照上面compare:默认的排序方法,也可以把自定义的方法写在这里,给对象排序
  49.         NSComparisonResult result = [obj1 compare:obj2];
  50.         return result;
  51.     }];
  52.     NSLog(@"排序后:%@",sortedArray);
  53. }

  54. 3、高级排序(sortedArrayUsingDescriptors:)
  55. 如果是这样一种情况呢?Person类里有另外一个类的变量,比如说Person类除了name,age变量,还有一辆车Car类型,Car类里有个name属性。对Person对象进行排序,有这样的要求:按照Car的name排序,如果是同一辆车,也就是Car的name相同,那么再按照年龄进行排序,如果年龄也相同,最后按照Person的name进行排序。

  56. 上面这样就要使用第三种方法,利用排序描述器,不多说,有兴趣可以看看API介绍。代码如下:

  57. 首先写个Car类,实现类Car.m代码如下:

  58. #import "Car.h"
  59. @implementation Car

  60. +(Car *)initWithName:(NSString *)name{
  61.     Car *car = [Car alloc] init];
  62.     car.name = name;
  63.     return car;
  64. }

  65. @end
  66. 然后改写Person类,实现类Person.m代码如下:

  67. #import "Person.h"
  68. #import "Car.h"
  69. @implementation Person

  70. +(Person *)personWithAge:(int)age withName:(NSString *)name withCar:(Car *)car{
  71.     Person *person = [[Person alloc] init];
  72.     person.age = age;
  73.     person.name = name;
  74.     person.car = car;
  75.     return person;
  76. }

  77. //这里重写description方法,用于最后测试排序结果显示
  78. -(NSString *)description{
  79.     return [NSString stringWithFormat:@"age is %zi , name is %@, car is %@",_age,_name,_car.name];
  80. }

  81. @end
  82. 主函数代码如下:

  83. void sortArray4(){
  84.         //首先来3辆车,分别是奥迪、劳斯莱斯、宝马
  85.         Car *car1 = [Car initWithName:@"Audio"];
  86.         Car *car2 = [Car initWithName:@"Rolls-Royce"];
  87.         Car *car3 = [Car initWithName:@"BMW"];
  88.         
  89.         //再来5个Person,每人送辆车,分别为car2、car1、car1、car3、car2
  90.         Person *p1 = [Person personWithAge:23 withName:@"zhangsan" withCar:car2];
  91.         Person *p2 = [Person personWithAge:21 withName:@"zhangsan" withCar:car1];
  92.         Person *p3 = [Person personWithAge:24 withName:@"lisi" withCar:car1];
  93.         Person *p4 = [Person personWithAge:23 withName:@"wangwu" withCar:car3];
  94.         Person *p5 = [Person personWithAge:23 withName:@"wangwu" withCar:car2];

  95.    
  96.         //加入数组
  97.         NSArray *array = [NSArray arrayWithObjects:p1,p2,p3,p4,p5, nil];
  98.         
  99.         //构建排序描述器
  100.         NSSortDescriptor *carNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"car.name" ascending:YES];
  101.         NSSortDescriptor *personNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
  102.         NSSortDescriptor *personAgeDesc = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
  103.         
  104.         //把排序描述器放进数组里,放入的顺序就是你想要排序的顺序
  105.         //我这里是:首先按照年龄排序,然后是车的名字,最后是按照人的名字
  106.         NSArray *descriptorArray = [NSArray arrayWithObjects:personAgeDesc,carNameDesc,personNameDesc, nil];
  107.         
  108.         NSArray *sortedArray = [array sortedArrayUsingDescriptors: descriptorArray];
  109.         NSLog(@"%@",sortedArray);
  110. }
  111. 结果如下:



  112. 从结果看出,先按照age排序,如果age相同,按照car排序,如果car相同,按照name排序。

  113. (注意:上面两种排序方法要想实现字符串显示,请重写description方法)
复制代码



评分

参与人数 1技术分 +1 收起 理由
jing迪 + 1

查看全部评分

回复 使用道具 举报 2 0
董月峰 发表于 2014-4-19 07:49
转自本人博客http://850361034.blog.163.com/blog/static/32803809201436111445914/

受教了。:handshake
回复 使用道具 举报
顶。董哥很犀利啊。总结很到位
回复 使用道具 举报
董月峰 发表于 2014-4-19 07:49
转自本人博客http://850361034.blog.163.com/blog/static/32803809201436111445914/

     厉害     谢谢兄弟
回复 使用道具 举报
这么牛的帖子,看着怎么这么费劲啊
回复 使用道具 举报
JAH562 中级黑马 2014-10-16 10:20:33
7#
用不可变的数组 排序 会 返回一个排序好新数组 调用ortedArrayUsingSelector:selector(compare:)
回复 使用道具 举报
JAH562 中级黑马 2014-10-16 11:06:28
8#
用NSarray 中的sortedArrayUsingSelector:selector@(compare;) 返回一个排序好的新数组
用NSMutableArray sortedUsingSelector:selector@(compare;)返回本数组即可
如果传入的是对象 要求特别排序 在selector@()传比较器
回复 使用道具 举报
墓笙 中级黑马 2014-12-22 23:02:10
9#
董月峰 发表于 2014-4-19 07:49
转自本人博客http://850361034.blog.163.com/blog/static/32803809201436111445914/

征用了。。。。。
回复 使用道具 举报
正好有用,学习了
回复 使用道具 举报
董月峰 发表于 2014-4-19 07:49
转自本人博客http://850361034.blog.163.com/blog/static/32803809201436111445914/

请教一下大神,NSLog(@"%@",sortedArray);这个只是显示类名,和元素地址,如何能具体显示里面的信息啊,比如:每一天先这样显示{zhangsan ,BMW,20}
            
回复 使用道具 举报
人外...有人 发表于 2015-4-26 00:16
请教一下大神,NSLog(@"%@",sortedArray);这个只是显示类名,和元素地址,如何能具体显示里面的信息啊, ...

重写description
回复 使用道具 举报
这个oc基础里面应该没有将的吧
回复 使用道具 举报
多谢了,解了燃眉之急
回复 使用道具 举报
学习了!
回复 使用道具 举报
高手!  受教了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马