美文网首页工作中用到的好技术
iOS - 排序: NSSortDescriptor

iOS - 排序: NSSortDescriptor

作者: SkyMing一C | 来源:发表于2017-11-23 12:23 被阅读428次
    图片源自网络

    排序规则描述类: NSSortDescriptor

    • NSSortDescriptor来指定排序规则, 对集合等进行排序时指定结果的排序规则
    • 可以对一个类的某个属性(下文中方法中的key参数)指定排序规则,
    • 可以对一个字符串集合进行指定排序规则, 这时, 只需要把参数key赋值为nil即可.

    在iOS的集合中,都有相应的扩展方法来使用NSSortDescriptor:

    • NSSet
      -NSArray<ObjectType> *)sortedArrayUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors
      
    • NSArray
      -(NSArray<ObjectType> *)sortedArrayUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors;
      
    • NSOrderedSet
      -(NSArray<ObjectType> *)sortedArrayUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors
      
    • NSMutableArray
      -(void)sortUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors;
      
    • NSMutableOrderedSet
      -(void)sortUsingDescriptors:(NSArray<NSSortDescriptor *> *)sortDescriptors
      
    其中的参数都是包含NSSortDescriptor的数组, 意味着我们可以同时指定多条规则来进行排序;(其优先级取决于在数组中的先后顺序)

    NSSortDescriptor 的使用

    • 定义一个简单的Model类

          // Model.h
      @class SubModel;
      @interface Model : NSObject
      
      @property (nonatomic, copy) NSString *name;
      @property (nonatomic, assign) BOOL sex;
      @property (nonatomic, assign) double height;
      @property (nonatomic, assign) int age;
      @end
      
      // Model.m
      @implementation Model
      @end
      
    • 生成假数据:

        NSArray *nameArray = @[@"小白", @"大白", @"老白", @"艾尔", @"黑山", @"张三", @"李四", @"王五", @"范晶", @"荆南", @"昔日", @"安安"];
        NSArray *ageArray = @[@3, @32, @45, @22, @32, @27, @15, @22, @55, @34, @32, @22];
        NSArray *heightArray = @[@100, @166, @180, @165, @163, @176, @174, @183, @186, @178, @167, @160];
        
        NSMutableArray *originalArray = [NSMutableArray arrayWithCapacity:nameArray.count];
            for (int i = 0; i<nameArray.count; i++) {
            
            Model *model = [[Model alloc]init];
            model.name = nameArray[i];
            model.age = [ageArray[i] intValue];
            model.height = [heightArray[i] doubleValue];
            [originalArray addObject:model];
         }
      
    • 初始化NSSortDescriptor :

      • + (instancetype)sortDescriptorWithKey:(nullable NSString *)key ascending:(BOOL)ascending
      • - (instancetype)initWithKey:(nullable NSString *)key ascending:(BOOL)ascending
        • 参数

        key : 排序key, 某个对象的属性名称; 如果对字符串进行排序, 则传nil
        ascending : 是否升序, YES-升序, NO-降序

        • 使用范例:
        //创建排序规则NSSortDescriptor
        //key :按照age属性 升序排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
        //给数组添加排序规则
        [originalArray sortUsingDescriptors:@[sort]];
        // 输出排序结果
        
         for (Model *model in originalArray) {
            NSLog(@"age: %d,height: %.1f name: %@", model.age,model.height, model.name);
        }
          /**
         age: 3 ,height: 100.0 name: 小白
         age: 15,height: 174.0 name: 李四
         age: 22,height: 165.0 name: 艾尔
         age: 22,height: 183.0 name: 王五
         age: 22,height: 160.0 name: 安安
         age: 27,height: 176.0 name: 张三
         age: 32,height: 166.0 name: 大白
         age: 32,height: 163.0 name: 黑山
         age: 32,height: 167.0 name: 昔日
         age: 34,height: 178.0 name: 荆南
         age: 45,height: 180.0 name: 老白
         age: 55,height: 186.0 name: 范晶
         */
        
        • 可同时指定多个规则:其优先级取决于在数组中的先后顺序
        //创建排序规则NSSortDescriptor
        //key :按照age属性 升序排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
        //age 相同 按照height属性 升序排序
        NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];
        //给数组添加排序规则
        [originalArray sortUsingDescriptors:@[sort,sort1]];
        // 输出排序结果
        
        for (Model *model in originalArray) {
        SLog(@"age: %d,height: %.1f name: %@", model.age,model.height, model.name);
        }
        /**
        age: 3 ,height: 100.0 name: 小白
        age: 15,height: 174.0 name: 李四
        age: 22,height: 160.0 name: 安安
        age: 22,height: 165.0 name: 艾尔
        age: 22,height: 183.0 name: 王五
        age: 27,height: 176.0 name: 张三
        age: 32,height: 163.0 name: 黑山
        age: 32,height: 166.0 name: 大白
        age: 32,height: 167.0 name: 昔日
        age: 34,height: 178.0 name: 荆南
        age: 45,height: 180.0 name: 老白
        age: 55,height: 186.0 name: 范晶
        */
        /** 其中age相同的按照height属性 升序排序
        age: 22,height: 160.0 name: 安安
        age: 22,height: 165.0 name: 艾尔
        age: 22,height: 183.0 name: 王五
        
        age: 32,height: 163.0 name: 黑山
        age: 32,height: 166.0 name: 大白
        age: 32,height: 167.0 name: 昔日
        
        */
        
      • + (instancetype)sortDescriptorWithKey:(nullable NSString *)key ascending:(BOOL)ascending selector:(nullable SEL)selector
      • - (instancetype)initWithKey:(nullable NSString *)key ascending:(BOOL)ascending selector:(nullable SEL)selector
        • 参数

        key : 排序key, 某个对象的属性名称
        ascending : 是否升序, YES-升序, NO-降序
        selector : SEL选择器,自定义排序规则, 如果需要自己定义排序规则, 可传递此方法 (自定义方法的返回值为NSComparisonResult).

        • 如果待比较的属性是字符串(NSString)类型, SEL选择器使用其默认的方法: localizedStandardCompare: 它将根据当前语言环境的语言规则进行排序(语言环境可能会根据大小写,变音符号等等的顺序而发生改变)
        //创建排序规则NSSortDescriptor
        //key :按照name属性 升序排序 SEL选择器使用其默认的方法: localizedStandardCompare: 
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedStandardCompare:)];
        //给数组添加排序规则
        [originalArray sortUsingDescriptors:@[sort]];
        // 输出排序结果
        
        for (Model *model in originalArray) {
            SLog(@"name: %@ age: %d,height: %.1f ", model.name, model.age,model.height);
        }
        /**
         name: 艾尔 age: 22,height: 165.0
         name: 安安 age: 22,height: 160.0
         name: 大白 age: 32,height: 166.0
         name: 范晶 age: 55,height: 186.0
         name: 黑山 age: 32,height: 163.0
         name: 荆南 age: 34,height: 178.0
         name: 老白 age: 45,height: 180.0
         name: 李四 age: 15,height: 174.0
         name: 王五 age: 22,height: 183.0
         name: 昔日 age: 32,height: 167.0
         name: 小白 age: 3 ,height: 100.0
         name: 张三 age: 27,height: 176.0
         */
        
        • 如果是其他的类型, 比如int, double等, 就需要对其类别(基本类型要对NSNumber)进行扩展;

          • 使用范例:按年龄进行排序, 修改其排序方法: ascending 为YES时, 让其降序排列
            • 对NSNumber类型写一个类目:
            // NSNumber+mySort.h
            @interface NSNumber (mySort)
            
            - (NSComparisonResult)mySort:(NSNumber *)num;
            @end
            
            // NSNumber+mySort.m
            @implementation NSNumber (mySort)
            - (NSComparisonResult)mySort:(NSNumber *)num {
            
              if (self == num) {
                return NSOrderedSame;
                } else if (self > num) {
              // 当自身大于num时, 本应该返回 NSOrderedDescending , 这里反转其结果, 使返回 NSOrderedAscending
             return NSOrderedAscending;
               }else {
               return NSOrderedDescending;
               }
            }
            @end
            
            • 使用NSSortDescriptor:
              //创建排序规则NSSortDescriptor
                //key :按照name属性 升序排序 SEL选择器使用扩展方法:mySort:(NSNumber)
                NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES selector:@selector(mySort:)];
                //给数组添加排序规则
                [originalArray sortUsingDescriptors:@[sort]];
                // 输出排序结果
            
                for (Model *model in originalArray) {
                    SLog(@"age: %d,height: %.1f name: %@",model.age,model.height, model.name);
                }
                /**
                age: 55,height: 186.0 name: 范晶
                age: 45,height: 180.0 name: 老白
                age: 34,height: 178.0 name: 荆南
                age: 32,height: 166.0 name: 大白
                age: 32,height: 163.0 name: 黑山
                age: 32,height: 167.0 name: 昔日
                age: 27,height: 176.0 name: 张三
                age: 22,height: 165.0 name: 艾尔
                age: 22,height: 183.0 name: 王五
                age: 22,height: 160.0 name: 安安
                age: 15,height: 174.0 name: 李四
                age: 3 ,height: 100.0 name: 小白
                */
            
      • + (instancetype)sortDescriptorWithKey:(nullable NSString *)key ascending:(BOOL)ascending comparator:(NSComparator)cmptr
      • - (instancetype)initWithKey:(nullable NSString *)key ascending:(BOOL)ascending comparator:(NSComparator)cmptr
        • 参数

        key : 排序key, 某个对象的属性名称
        ascending : 是否升序, YES-升序, NO-降序
        cmptr: NSComparator比较器,block方法, 可以在其中指定比较规则,返回值为NSComparisonResult

        //创建排序规则NSSortDescriptor
        //key :按照name属性 升序排序 NSComparator比较器,一个block, 可以在其中指定比较规则
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES comparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
            
            if (obj1 == obj2) {
                return NSOrderedSame;
            } else if (obj1 > obj2){
                // 当obj1大于obj2时, 本应该返回 NSOrderedDescending , 这里反转其结果, 使返回 NSOrderedAscending
                return NSOrderedAscending;
            } else {
                return NSOrderedDescending;
            }
        }];
        //给数组添加排序规则
        [originalArray sortUsingDescriptors:@[sort]];
        // 输出排序结果
        
        for (Model *model in originalArray) {
            SLog(@"age: %d,height: %.1f name: %@",model.age,model.height, model.name);
        }
        /**
        age: 55,height: 186.0 name: 范晶
        age: 45,height: 180.0 name: 老白
        age: 34,height: 178.0 name: 荆南
        age: 32,height: 166.0 name: 大白
        age: 32,height: 163.0 name: 黑山
        age: 32,height: 167.0 name: 昔日
        age: 27,height: 176.0 name: 张三
        age: 22,height: 165.0 name: 艾尔
        age: 22,height: 183.0 name: 王五
        age: 22,height: 160.0 name: 安安
        age: 15,height: 174.0 name: 李四
        age: 3 ,height: 100.0 name: 小白
         */
      

    参考

    NSSortDescriptor[US]

    iOS: NSSortDescriptor 集合排序

    [iOS] 浅析排序规则描述类: NSSortDescriptor

    NSSortDescriptor 应该如何用方法自定义排序规则?

    相关文章

      网友评论

        本文标题:iOS - 排序: NSSortDescriptor

        本文链接:https://www.haomeiwen.com/subject/cocovxtx.html