黑马程序员技术交流社区

标题: nsarray如何自定义排序? [打印本页]

作者: Devchen    时间: 2014-7-20 23:00
标题: nsarray如何自定义排序?
看了系统的sortUsingDescriptors很晕,还有NSSortDescriptor,有谁可以讲讲……
作者: fantacyleo    时间: 2014-7-20 23:23
我比较喜欢用sortedArrayUsingComparator: ^NSComparisonResult(id obj1, id obj2) 自定义一个block传进去。
这个block就是你告诉NSArray,对于数组中的两个元素:obj1和obj2,它们之间的大小关系应该怎么确定,所谓确定大小关系,就是指明:
什么条件下返回NSOrderedSame 即obj1 == obj2
什么条件下返回NSOrderedAscending 即obj1 < obj2
什么条件下返回NSOrderedDescending 即obj1 > ojb2
明确了大小关系,NSArray就可以调用它内部定义好的排序方法来进行排序了。
作者: Devchen    时间: 2014-7-21 10:15
fantacyleo 发表于 2014-7-20 23:23
我比较喜欢用sortedArrayUsingComparator: ^NSComparisonResult(id obj1, id obj2) 自定义一个block传进去 ...

一下明了了许多,这就试试去
作者: Devchen    时间: 2014-7-21 12:12
fantacyleo 发表于 2014-7-20 23:23
我比较喜欢用sortedArrayUsingComparator: ^NSComparisonResult(id obj1, id obj2) 自定义一个block传进去 ...

selector也挺好用特别适合自定义方法。描述器那个感觉灵活性不大
作者: fantacyleo    时间: 2014-7-21 13:31
本帖最后由 fantacyleo 于 2014-7-21 13:33 编辑
Devchen 发表于 2014-7-21 12:12
selector也挺好用特别适合自定义方法。描述器那个感觉灵活性不大

如果你要按多个property进行排序,descriptor就很方便了。比如按Person的名字排序,相同名字再按年龄排序:
  1. #import <Foundation/Foundation.h>

  2. @interface Person : NSObject

  3. @property (nonatomic, strong) NSString *name;
  4. @property (nonatomic, assign) int age;

  5. @end

  6. @implementation Person
  7. - (id)initWithName:(NSString *)name andAge:(int)age
  8. {
  9.     self = [super init];
  10.     if (self) {
  11.         _name = name;
  12.         _age = age;
  13.     }
  14.     return self;
  15. }

  16. - (NSString *)description
  17. {
  18.     return [NSString stringWithFormat:@"%@:%d", self.name, self.age];
  19. }
  20. @end


  21. int main(int argc, const char * argv[])
  22. {

  23.     @autoreleasepool {
  24.         
  25.         Person *p1  = [[Person alloc] initWithName:@"Jack" andAge:20];
  26.         Person *p2  = [[Person alloc] initWithName:@"John" andAge:21];
  27.         Person *p3  = [[Person alloc] initWithName:@"Jack" andAge:18];
  28.         NSArray *strArr = @[p1, p2, p3];
  29.         
  30.         NSSortDescriptor *sortName = [NSSortDescriptor
  31.                                       sortDescriptorWithKey:@"name"
  32.                                       ascending:YES];
  33.         
  34.         NSSortDescriptor *sortAge = [NSSortDescriptor
  35.                                       sortDescriptorWithKey:@"age"
  36.                                       ascending:YES];
  37.         NSArray *sorted = [strArr sortedArrayUsingDescriptors:@[sortName, sortAge]];
  38.         NSLog(@"%@", sorted);
  39.         
  40.     }
  41.     return 0;
  42. }
复制代码

作者: fantacyleo    时间: 2014-7-21 13:42
如果不用descriptor来写,就得写一大堆if了。按2个条件排序还算好:
if ([obj1 name] compare:[obj2 name]] == 0) {
    if ([obj1 age] == [obj2 age])
        return NSOrderedSame;
    else if ([obj1 age] < [obj2 age])
        return NSOrderedAscending;
    else
        return NSOrderedDescending;
}
return [obj1 name] compare:[obj2 name]];
。如果按3个、4个条件排序,而且有的条件还不像string这样事先定义了compare方法,嵌套if就恐怖了
作者: Devchen    时间: 2014-7-26 18:42
fantacyleo 发表于 2014-7-21 13:42
如果不用descriptor来写,就得写一大堆if了。按2个条件排序还算好:
if ([obj1 name] compare:[obj2 name]] ...

这个签名是怎么搞的“财经专业……”,没找到地方,要级别吗?
作者: fantacyleo    时间: 2014-7-26 19:05
Devchen 发表于 2014-7-26 18:42
这个签名是怎么搞的“财经专业……”,没找到地方,要级别吗?

设置-个人信息
作者: a_dream    时间: 2014-7-26 21:30
这个是Foundation框架里面的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2