• 数组谓词查询法 NSPredicate


    • NSPredicate:谓词
      • 字面翻译是这个意思,但是我觉得谓词这个词太难以理解了
      • NSPredicate的具体用途应该还是过滤,类似于过滤条件之类的,相当于一个主语的谓语,所以说会是谓词这个名字。(我是这么理解的)

    1、NSPredicate的创建

    • 我们看到创建谓词使用类方法predicateWithFormat: (NSString*) format,format 里的东西真的和 SQL 的 where 条件差不多。
    • 另外,参数format 与NSLog 的格式化模版差不多,如果1 和 188.0 是传递过来的参数,你可以写成如下的形式:
    	@"pid>%d and height<%f",1,188.0
    

    2、NSPredicate中主要的几种运算方式

    • 2.1比较运算符 > 、< 、== 、 >= 、<= 、 !=

      例:@"number >= 99"
      
    • 2.2 逻辑运算符:AND、OR、NOT 这几个运算符计算并、或、非的结果。

    • 2.3 范围运算符:IN 、BETWEEN

      例:@"number BETWEEN {1,5}"
      @"address IN {'shanghai','nanjing'}"
      
    • 2.4 字符串本身:SELF

      例:@"SELF == 'APPLE'"
      
    • 2.5字符串相关:BEGINSWITH、ENDSWITH、CONTAINS

      例: @"name CONTAIN[cd] 'ang'" //包含某个字符串
      @"name BEGINSWITH[c] 'sh'" //以某个字符串开头
      @"name ENDSWITH[d] 'ang'" //以某个字符串结束
      
    • 注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。

    • 2.6 通配符:LIKE

      例:@"name LIKE[cd] '*er*'" //*代表通配符,Like也接受[cd].
      @"name LIKE[cd] '???er*'"
      
    • 2.7 正则表达式:MATCHES

      例:NSString *regex = @"^A.+e$"; //以A开头,e结尾
      @"name MATCHES %@",regex
      

    3、具体使用方法

    • 如何使用NSPredicate对一个自定义实体进行筛选

    • NSPredicate我暂时都是用于过滤的,否则我们过滤就需要自己写判断 写循环,去判断输出了。

    • 接下来就上代码和例子吧。

    • 3.1 建立一个实体类 Dog

      @property (copy   , nonatomic) NSString* name; 
      @property (assign , nonatomic) int       age ;
      
      • 这样我们就有一个类了
      • 我们创建 5只Dog的实体
      Dog * dog1=[Dog news];dog1.name=@"这是第一只Dog";dog1.age=@"11";
      Dog * dog2=[Dog news];dog2.name=@"这是第二只Dog";dog2.age=@"22";
      Dog * dog3=[Dog news];dog3.name=@"这是第三只Dog";dog3.age=@"33";
      Dog * dog4=[Dog news];dog4.name=@"这是第四只Dog";dog4.age=@"44";
      Dog * dog5=[Dog news];dog5.name=@"这是第五只Dog";dog5.age=@"55";
      
      • 不要吐槽我的Dogs的年龄 → 。→
      • 然后我们需要一个Array把他们都装进去
      NSArray * dogArr=@[dog1,dog2,dog3,dog4,dog5];
      
      • 酱紫所有的Dog都装到一个数组里了
    • 3.2 使用NSPredicate的筛选

      • 没有使用NSPredicate的筛选应该大家都会写,循环+判断。。。
      • 使用NSPredicate的筛选
      • 具体使用的代码
      //创建谓词的对象 谓词条件是基于KVC的,所以需要说明一点,加入Dog里面有个属性是Doginfo指向Doginfo类,在使用的时候 我们的条件就要写成Doginfo.xxx了。
      NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name=='这是第一只Dog' AND age ==11"];
      for(Dog * d in dogArr)
      {
          if([predicate evaluateWithObject:d])
          {
              NSLog(d.name);
          }
      }
      
      • 以上的代码打印出来的结果就是 这是第一只Dog

      • NSPredicate筛选一个对象逻辑还是很清晰的,不过这里比较麻烦的就是 还有一个循环,这里我们会发现数组提供了一个方法可以更方便的检索数组对象
        直接筛选出一个符合谓词的新数组。

      NSPredicate *pre = [NSPredicate predicateWithFormat:@"age >11"];
      NSMutableArray *arrayPre=[dogArr filteredArrayUsingPredicate: pre];
      
      • arrayPre里面的对象就会是 除了dog1之外的所有的dog。(至于为什么看我的条件...)

      • 看到这里发现NSPredicate 可以用于自定义的实体的检索、筛选,那如果用于 NSString,NSInteger,bool呢?那我们再看一段代码吧

      NSArray *arrays=[NSArray arrayWithObjects: @"Apple", @"Google", @"MircoSoft", nil];
      NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF=='Apple'"];
      
    • 3.3 使用NSPredicate在两个数组之间进行差异筛选

      • 上面这段代码是匹配字符串的时候 NSPredicate 需要如何声明
      NSArray* array = @[@"aa",@"bb"];
      NSArray* array2 = @[@"aa",@"bb",@"cc",@"dd"];
      NSPredicate* thePredicate = [NSPredicate predicateWithFormat:@"NOT(SELF in %@)",array];
      NSArray* arr3 = [array2 filteredArrayUsingPredicate:thePredicate];
      NSLog(@"%@",arr3);
      
      • 上面的代码输出结果 arr3={@"cc" ,@"dd"}
      • 这样大家就很容易理解了
      • SELF在前面有介绍过 可以往回翻阅一下
    • 3.4 如何使用正则筛选一个数组

      NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。
      NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
      if([pre evaluateWithObject: @"Apple"]){
          printf("YES
      ");
      } else {
          printf("NO
      ");
      }
      

    4、注意事项

    • 关于NSPredicate的其他说明和注意事项,以及技巧
    • 动态属性名
    • 假如你的代码如下
    NSPredicate *p = [NSPredicate predicateWithFormat:@"name = %@", @"name1"]; 
    
    • 显然代码没有任何问题,但是这个不是最好的写法我建议如下写法:
    NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
    NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
    @"name1", @"NAME",nil];
    NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
    
    • 这样看上去可能会让代码逻辑更清晰。

    • 当过滤条件字段都是动态的时候

    NSString *key = @"name";     
    NSString *value = @"name1";      
    NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ = %@", key, value];
    
    • 然后当你执行到第三行的时候代码就会报错!
    • 逻辑上没错误啊!!!为什么会出错呢?
    • NSPredicate要自动添加引号,所以最后得到的格式应该是@"'name' = 'name1'"。明显不对。要做的就是:
    NSPredicate *p = [NSPredicate predicateWithFormat:@"%K = %@", key, value]; 
    
  • 相关阅读:
    LeetCode 414. Third Maximum Number
    LeetCode 498. Diagonal Traverse
    LeetCode 520. Detect Capital
    LeetCode 503. Next Greater Element II
    LeetCode 496. Next Greater Element I
    LeetCode 508. Most Frequent Subtree Sum
    LeetCode 515. Find Largest Value in Each Tree Row
    LeetCode 516. Longest Palindromic Subsequence
    输入输出流
    java中举例说明对象调用静态成员变量
  • 原文地址:https://www.cnblogs.com/CH520/p/9393422.html
Copyright © 2020-2023  润新知