美文网首页IOS知识积累
【OC梳理】NSPredicate

【OC梳理】NSPredicate

作者: 忠橙_g | 来源:发表于2017-11-23 16:00 被阅读553次

    NSPredicate

    NSPredicate(谓词),可以根据定义的模糊查询条件,对内存对象进行过滤搜索。

    基本语法
    • 谓词表达式 : 由表达式、运算符和值构成。
      • 值:

      FALSE、NO:代表逻辑假
      TRUE、YES:代表逻辑真
      NULL、NIL:代表空值
      SELF:代表正在被判断的对象自身
      "string"或'string':代表字符串
      数组:和c中的写法相同,如:{'one', 'two', 'three'}。
      数值:包括证书、小数和科学计数法表示的形式
      十六进制数:0x开头的数字
      八进制:0o开头的数字
      二进制:0b开头的数字

      • 运算符:


    常见用途

    1.使用谓词进行正则匹配,例如:
    匹配手机号

    - (BOOL)checkPhoneNumber:(NSString *)phoneNumber
    {
        NSString *regex = @"^[1][3-8]\\d{9}$";
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
        return [pred evaluateWithObject:phoneNumber];
    }
    

    验证邮箱

    + (BOOL)validateEmail:(NSString *)email{
        NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
        NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 
        return [emailTest evaluateWithObject:email];
    }
    

    ps:使用正则匹配时,更推荐使用NSRegularExpression而不是NSPredicate,因为NSPredicate对某些表达式的匹配结果并不尽如人意。
    正则相关:正则表达式在IOS中的应用

    2.使用谓词过滤集合

    • NSArray提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合
    - (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate;
    
    • NSMutableArray提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素
    - (void)filterUsingPredicate:(NSPredicate *)predicate;
    
    • NSSet提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSSet集合,返回符合条件的元素组成的新集合
    - (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate;
    
    • NSMutableSet提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSMutableSet,剔除集合中不符合条件的元素
    - (void)filterUsingPredicate:(NSPredicate *)predicate;
    
    • NSOrderedSet提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSOrderedSet集合,返回符合条件的元素组成的新集合
    - (NSOrderedSet<ObjectType> *)filteredOrderedSetUsingPredicate:(NSPredicate *)p;
    
    • NSMutableOrderedSet提供了如下方法使用谓词来过滤集合
    //使用指定的谓词过滤NSMutableOrderedSet,剔除集合中不符合条件的元素
    - (void)filterUsingPredicate:(NSPredicate *)p;
    
    • 以上方法都可以在NSPredicate.h文件中找到。

    使用示例:
    创建数组,数组中的元素包含name和age两个属性

    NSArray *persons = ...
    

    定义谓词对象,谓词对象中包含了过滤条件
    (过滤条件中,使用self.name和直接用name的效果一样)

    //age小于30  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<30"];  
    
    //查询name=1的并且age大于40  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name='1' && age>40"]; 
    
    //name以a开头的  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'a'"];  
    //name以ba结尾的  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name ENDSWITH 'ba'"]; 
    
    //name为1/2/4,或者age为30/40
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN {'1','2','4'} || age IN{30,40}"];
    
     //like 匹配任意多个字符  
    //name中只要有s字符就满足条件  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '*s*'"];  
    //?代表一个字符,下面的查询条件是:name中第二个字符是s的  
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '?s'"]; 
    

    使用谓词条件过滤数组中的元素,过滤之后返回查询的结果

    NSArray *array = [persons filteredArrayUsingPredicate:predicate];  
    
    • 谓词的表达式中,如果要动态修改条件,可以使用占位符:
      在使用时,如果需要拼接属性名,其占位符为%K(注意大写)而不是%@,如:
    NSString * key = @"age";
    int age = 30;
    //拼接示例:
    [NSPredicate predicateWithFormat:@"%K < %d", key, age];
    

    如果想动态改变判断的范围,可以使用$ 开头的占位符:

    //用$AGE进行占位,可以动态修改$对应的值,这里的AGE可以是任意字符串
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < $AGE"];
    
    //修改AGE的值(AGE对应上面的$后的字符串),生成新的NSPredicate对象
    NSPredicate *newPredicate = [predicate predicateWithSubstitutionVariables:@{@"AGE":@30}];
    
    //使用newPredicate过滤数组
    NSArray *array = [persons filteredArrayUsingPredicate: newPredicate];
    

    PS:个人感觉用字符串拼接的方式设置表达式的自由度更高。

    相关文章

      网友评论

        本文标题:【OC梳理】NSPredicate

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