zoukankan      html  css  js  c++  java
  • Objective-C之NSArray(数组)默认排序与自定义排序

    在讲OC中数组的排序之前我先上一段代码,它是简单数组排序的一种方法(也就是元素是字符串或者数据的数组,因为后面要讲元素为类的数组排序)

    代码1:

    1 NSArray *sortArr4 = [sortArr3 sortedArrayUsingComparator:^NSComparisonResult/*代码块返回值类型*/(id obj1, id obj2)
    2         {
    3              return [obj1 compare:obj2];//根据比较结果,如果结果是1,则交换
    4         }];
    5         NSLog(@"%@",sortArr4);

    上面的程序中定义的一个sortArr4的数组,它来自于sortArr3的排序结果(注意:是升序)。第三行中的“obj1 compare:obj2”,还记得compare:是个什么东东吗?他是我们数组(NSString)那一节中的一个字符串比较方法,如下我把之前的代码复制过来了:

    代码2:

    2        NSComparisonResult/*枚举类型*/ result = [@"CBA" compare:@"abc" ] ;

          比较之后返回了一个名字为NSComparisonResult的枚举类型(取值-1(小于),0(等于),1(大于)),快看,它跟代码1中的“:^”后的名字是一样的。为什么呢?因为这必须要一样。compare:比较之后的返回值传向了NSArray的一个方法“sortedArrayUsingComparator:”,它内部机制是我们看不到的,因为OC代码不开源。我们只知道它获得了值1时,就是compare:比较返回值为1时,会把数组元素进行交换,应该类似于C语言中的冒泡排序,我估计它内部有循环机制,不然循环一次的位置调换是无法正确排序的。

          好了,上面的代码就是字符串排序的作用,大家有没有注意到"[]"阔的范围把整个函数都阔住了。其实,它不算是个函数,“{}”里面放的只是一个我们自定义的能返回NSComparisonResult的枚举类型范围的代码。我们也可以通过if.else来实现,只是那样不利于字符串的比较,假如数组里面是数据,那样用if.else就简单多了。   

    下面进入正题:

    代码3

    1       NSArray *sortArr = @[@"4",@"1",@"5",@"3"];
    2        NSArray *sortArr1 = [sortArr sortedArrayUsingSelector/*排序数组使用选择器*/:@selector(compare:)];
    3       //   @selector是关键字(告诉编译器要执行一个方法),后面跟的是函数或自定义函数,总之就是具有比较功能,能返回NSComparisonResult类型的函数
    4        //compare:返回调用结果比较:不带任何选项的选择:范围:和接收机的全部范围。
    5         NSLog(@"%@",sortArr1);
    6         
    7        // IOS提供一个sortedArrayUsingSelector ()函数,用于对字符串数组进行排序,方法会在排序后返回一个新的数组。
    8         //[array  sortedArrayUsingSelector (@selector(xxxx:))];
    9         //xxxx:方法需要你自己根据实际情况设定排序方式。有默认的排序方法 compare :

         代码注释中已将讲了“compare:”是一个方法,它也可以我们自己定义,当数组元素比较复杂时,“compare:”无法满足比较。例如一个元素为学生对象的数组,数组每个元素都包含了学生的年龄,性别,分数,姓名等等,那用“compare:”怎么比?是没办法比得。所以就需要我们自定义方法,别的地方都不用改变,只需要把“compare:”改为我们自定义的方法就行了。那么这个方法怎么定义呢?首先,我们要明确的知道,这个方法有形参,形参应该与数组元素同等类型,因为要对元素(类的对象)的部分成员进行比较;有返回值并且是NSComparisonResult类型的返回值。下面看代码:

    代码4:

    1 @interface Student : NSObject
    2 
    3 @property(nonatomic,strong)NSString *name;
    4 @property(nonatomic,assign) int age;
    5 
    6 -(NSComparisonResult)compareWithName:(Student *)stu;//比较name的方法,返回Foundation框架方法的够处理的NSComparisonResult类型
    7 -(NSComparisonResult)compareWithAge:(Student *)stu;//比较age的方法,返回Foundation框架方法的够处理的NSComparisonResult类型
    8 
    9 @end

          代码4是定义Student类的.h文件,首先声明了名字和年龄的属性,后面声明了前面讲到的需要取代替"compare:"的一个比较方法,就是自定义方法。代码5中是该方法的实现部分。

    代码5:

     1 @implementation Student
     2 -(NSComparisonResult)compareWithName:(Student *)stu
     3 {
     4     return [self.name compare:stu.name];
     5 }
     6 -(NSComparisonResult)compareWithAge:(Student *)stu
     7 {
     8     if( self.age < stu.age ) return -1;
     9     else if( self.age == stu.age ) return 0;
    10     else return 1;
    11 }
    12 -(NSString *)description//方法重写
    13 {
    14     return [NSString stringWithFormat:@"%@,%i",_name,_age];
    15 }
    16 @end

         注意注释处的方法重写部分,假如利用代码6中的17、18行输出方法会输出地址。所以在这里重写了description(描述方法),就是把类对象中的年龄和姓名以字符串形式拼接起来,这样的话可以直接对数组进行打印输出。

    代码6:

     1 int main(int argc, const char * argv[])
     2 {
     3     @autoreleasepool
     4     {
     5         Student *student1 = [[Student alloc] init];
     6         Student *student2 = [[Student alloc] init];
     7         Student *student3 = [[Student alloc] init];
     8         student1.name = @"zhangsan";
     9         student1.age = 16;
    10         student2.name = @"lisi";
    11         student2.age = 20;
    12         student3.name = @"wangwu";
    13         student3.age = 23;
    14         NSArray *myAray = @[student1,student2,student3];
    15         NSArray *meToArray = [myAray sortedArrayUsingSelector:@selector(compareWithName:)];
    16         NSArray *comeToArray = [myAray sortedArrayUsingSelector:@selector(compareWithAge:)];
    17 //        NSLog(@"%@",meToArray);//打印的是地址
    18 //        NSLog(@"%@",comeToArray);
    19         NSLog(@"%@",meToArray);//打印的是地址
    20         NSLog(@"%@",comeToArray);
    21         
    22     }
    23     return 0;
    24 }
    1 //第二种方法,描述器排序        
    2         //先创建排序条件:key对应要排序的对象的属性名字
    3         NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
    4         NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES];
    5         //将描述条件放入排序数组(用于盛放排序条件,可以多个)
    6         //先按成绩升序排序,成绩一样的情况,再按年龄升序排序
    7         NSArray *desArr = @[sort,sort1];
    8         NSArray *sortArr1 = [myAray sortedArrayUsingDescriptors:desArr]; 
    9 NSLog(@"--->%@",sortArr1);

    一、 NSMutableArray *sss = [NSMutableArray arrayWithCapacity:0];
    NSArray *ddd = @[@"12323456",@"155",@"8588" ];
    [sss addObjectsFromArray:ddd];
    [sss removeObjectAtIndex:0];

    二、 NSMutableArray *sss = [NSMutableArray arrayWithCapacity:0];
    NSArray *ddd = @[@"12323456",@"155",@"8588" ];
    [sss copy];
    [sss removeObjectAtIndex:0];

    三、 NSMutableArray *sss = [NSMutableArray arrayWithCapacity:0];
    NSArray *ddd = @[@"12323456",@"155",@"8588" ];
    [sss arrayByAddingObjectsFromArray:ddd];
    [sss removeObjectAtIndex:0];

    其中只有第一个程序可以正常运行

  • 相关阅读:
    小知识:关于String的创建
    JSON学习笔记,数组
    JSON学习笔记,对象
    爱乐之城 La La Land
    TwoSampleMR包出现报错: None of the specified columns present
    无亲缘关系为何IBD结果为同卵双胞胎/重复样本
    本周最新文献速递20210321
    本周最新文献速递20210314
    使用 KaKs Calculator 计算 KaKs 的衍生问题解答
    本周最新文献速递20210307
  • 原文地址:https://www.cnblogs.com/liuguan/p/4911994.html
Copyright © 2011-2022 走看看