zoukankan      html  css  js  c++  java
  • OC学习14——谓词

    一、谓词的基本概念与使用

    1、谓词(NSPredicate)用于定义一个逻辑条件,通过该条件可执行搜索或内存中的过滤操作。上一篇文章中介绍的集合都提供了使用谓词对集合进行过滤的方法。OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据。非常方便。在Java中是没有这种技术的,但是有开源的框架已经实现了此功能。

    2、创建谓词之后,如果谓词中没有占位符,则可以直接使用NSPredicate的evaluateWithObject:方法计算谓词的结果,该结果总是一个BOOL值;

     1 #import <Foundation/Foundation.h>
     2 #import "FKUser.h"
     3 
     4 int main(int argc , char * argv[])
     5 {
     6     @autoreleasepool{
     7         // 创建谓词,要求name的以s开头
     8         NSPredicate* pred = [NSPredicate predicateWithFormat:
     9             @"name like 's*'"];
    10         FKUser* user1 = [[FKUser alloc] initWithName:@"sun"
    11             pass:@"123"];
    12         // 对user1对象使用谓词执行判断。
    13         BOOL result1 = [pred evaluateWithObject:user1];
    14         NSLog(@"user1的name是否以s开头:%d", result1);
    15         FKUser* user2 = [[FKUser alloc] initWithName:@"bai"
    16             pass:@"563"];
    17         // 对user1对象使用谓词执行判断。                
    18         BOOL result2 = [pred evaluateWithObject:user2];
    19         NSLog(@"user2的name是否以s开头:%d", result2);
    20     }
    21 }
    NSPredicate示例

    3、谓词本身就代表了一个逻辑条件,计算谓词的结果就返回了BOOL类型的值,谓词一个常用的功能就说对集合进行过滤。当程序使用谓词对集合元素进行过滤时,程序会自动遍历集合元素,并根据集合元素计算谓词的值,只有根据某个集合元素计算谓词并返回YES时,该集合元素才会被保留下来。

      NSArray提供了如下方法使用谓词来过滤集合:

    • -(NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSArray集合,返回集合中符合谓词条件的元素组成新集合

      NSMutableArray提供了如下方法使用谓词来过滤集合:

    • -(void)filteredUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSMutableArray集合,剔除该集合中不符合谓词条件的元素

      NSSet提供如下方法使用谓词进行过滤集合:

    • -(NSSet *)filteredSetUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSArray集合,返回集合中符合谓词条件的元素组成新集合

     NSMutableSet提供了如下方法使用谓词来过滤集合:

    • -(void)filteredUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSMutableSet集合,剔除该集合中不符合谓词条件的元素
     1 #import <Foundation/Foundation.h>
     2 #import "FKUser.h"
     3 
     4 int main(int argc , char * argv[])
     5 {
     6     @autoreleasepool{
     7         NSMutableArray* array = [NSMutableArray
     8             arrayWithObjects: [NSNumber numberWithInt:50],
     9             [NSNumber numberWithInt:50],
    10             [NSNumber numberWithInt:42],
    11             [NSNumber numberWithInt:20],
    12             [NSNumber numberWithInt:64],
    13             [NSNumber numberWithInt:56],nil];
    14         // 创建谓词,要求该对象自身的值大于50
    15         NSPredicate* pred1 = [NSPredicate predicateWithFormat:
    16             @"SELF > 50"];
    17         // 使用谓词执行过滤,过滤后只剩下值大于50的集合元素
    18         [array filterUsingPredicate:pred1];
    19         NSLog(@"值大于50的元素:%@" , array);
    20         NSSet* set = [NSSet setWithObjects:
    21             [[FKUser alloc] initWithName:@"孙悟空"
    22                  pass:@"343"],
    23             [[FKUser alloc] initWithName:@"金角大王"
    24                  pass:@"231"],
    25             [[FKUser alloc] initWithName:@"猪八戒"
    26                  pass:@"659"],
    27             [[FKUser alloc] initWithName:@"太上老君"
    28                  pass:@"743"],
    29             [[FKUser alloc] initWithName:@"银角大王"
    30                  pass:@"985"], nil];
    31         // 创建谓词,要求该对象的name值中包含'大王'
    32         NSPredicate* pred2 = [NSPredicate predicateWithFormat:
    33             @"name CONTAINS '大王'"];    
    34         // 执行过滤,过滤后集合只剩下两个元素                
    35         NSSet* newSet = [set filteredSetUsingPredicate:pred2];
    36         NSLog(@"%@" , newSet);                                                                
    37     }
    38 }
    NSPredicate过滤集合

     4、在前面的程序中使用谓词的对象总是固定的,总是用指定对象的固定属性与固定的值进行比较,如果符合条件,则返回YES,否则返回NO。有时候我们需要在谓词表达式中使用变量,则可以考虑在谓词表达式中使用占位符参数,在谓词表达式中支持以下两个占位符参数:

    • %K:该占位符用于动态传入属性名。
    • %@:该占位符用于动态设置属性值。取决于要设置属性值的类型,该占位符也可以改成%d、%g等占位符

      如果谓词中由占位符参数,则需要经过两步来计算谓词的结果:

    1.  调用predicateWithSubstitutionVariables:方法为占位符参数设置参数值,该方法返回一个可用的NSPredicate对象
    2. 执行谓词的evaluateWithObject:方法计算谓词的返回结果
       1 #import <Foundation/Foundation.h>
       2 #import "FKUser.h"
       3 
       4 int main(int argc , char * argv[])
       5 {
       6     @autoreleasepool{
       7         NSSet* set = [NSSet setWithObjects:
       8             [[FKUser alloc] initWithName:@"孙悟空"
       9                  pass:@"343"],
      10             [[FKUser alloc] initWithName:@"金角大王"
      11                  pass:@"231"],
      12             [[FKUser alloc] initWithName:@"猪八戒"
      13                  pass:@"659"],
      14             [[FKUser alloc] initWithName:@"太上老君"
      15                  pass:@"743"],
      16             [[FKUser alloc] initWithName:@"银角大王"
      17                  pass:@"598"], nil];
      18         NSString* propPath = @"name";
      19         NSString* value = @"大王";
      20         // 创建谓词,该谓词中包含了2个占位符
      21         // 后面的2个变量用于为占位符设置参数值,因此实际上相当于创建了谓词表达式 "name CONTAINS '大王'"
      22         NSPredicate* pred = [NSPredicate predicateWithFormat:
      23             @"%K CONTAINS %@" , propPath , value];
      24         // 执行过滤,过滤后集合只剩下两个元素
      25         NSSet* newSet = [set filteredSetUsingPredicate:pred];
      26         NSLog(@"%@" , newSet);
      27         // 创建谓词,该谓词表达式中使用%K占位符,该占位符使用pass代替,所以该代码相当于创建谓词表达式 "pass CONTAINS $SUBSTR"
      28         // $SUBSTR相当于一个变量,需要我们调用时为它设置值
      29         NSPredicate* predTemplate = [NSPredicate predicateWithFormat:
      30             @"%K CONTAINS $SUBSTR" , @"pass"];
      31         // 使用NDDictionary指定SUBSTR的值为'43',这就相当于创建了谓词表达式"pass CONTAINS '43'"
      32         NSPredicate* pred1 = [predTemplate 
      33             predicateWithSubstitutionVariables:
      34             [NSDictionary dictionaryWithObjectsAndKeys:
      35                 @"43" , @"SUBSTR", nil]];
      36         // 执行过滤,过滤后集合只剩下两个元素
      37         NSSet* newSet1 = [set filteredSetUsingPredicate:pred1];
      38         NSLog(@"%@" , newSet1);    
      39         // 使用NDDictionary指定SUBSTR的值为'59'
      40         NSPredicate* pred2 = [predTemplate 
      41             predicateWithSubstitutionVariables:
      42             [NSDictionary dictionaryWithObjectsAndKeys:
      43                 @"59" , @"SUBSTR", nil]];
      44         // 执行过滤,过滤后集合只剩下两个元素
      45         NSSet* newSet2 = [set filteredSetUsingPredicate:pred2];
      46         NSLog(@"%@" , newSet2);
      47     }
      48 }
      NSPredicate使用占位符

    二、谓词表达式语法

    1、基本比较运算符:=、==(是否相等);>=、=>(左边是否大于或等于右边);<=、=<(左边是否小于或等于右边);>(左边是否大于右边);<(左边是否小于右边);!=、<>(不等于);BETWEEN(必须满足表达式 BETWEEN{下限,上限} 的格式,在范围内左右取等号)。

    2、基本逻辑运算符:

    • AND、&&:逻辑与
    • OR、||:逻辑或
    • NOT、!:逻辑非

    3、字符串比较运算符:

    • BEGINSWITH:检查某个字符串是否以指定的某个子串开头
    • ENDSWITH:检查某个字符串是否以指定的某个子串结尾
    • CONTAINS:检查某个字符串是否包含指定的某个子串
    • LIKE:检查某个字符串是否匹配指定的字符串模板
    • MATCHES:检查某个字符串是否匹配指定的正则表达式

      上述方法都是区分大小写的,如果要不区分大小写和重音符号,则可以在运算符后面使用[c]、[d]选项,其中[c]指定不区分大小写,[d]指定不区分重音符号。eg:“name BEGINSWITH[c][d] fkja”,则不管name值是FKJava还是fkjava都将返回YES。

    4、操作集合的运算符:

    • ANY、SOME:指定只要集合中任意一个元素满足条件,即可返回YES。
    • ALL:指定所有元素满足才返回YES。
    • NONE:指定没有任何元素满足条件才返回YES。
    • IN:只有当左边的表达式或值出现在右边的集合中才会返回YES。
    • array[index]:返回array数组中索引为index处的元素
    • array[FIRST]:返回array数组中第一个元素
    • array[LAST]:返回array数组中最后一个元素
    • array[SIZE]:返回array数组中元素的个数。

    5、直接量:

      在谓词表达式中,使用双引号和单引号的效果是一样的。但是单引号只能用单引号结束,不能混用。

    • FALSE、NO:逻辑假
    • TRUE、YES:逻辑真
    • NULL、NIL:代表一个空值
    • SELF:代表正在被判断的对象
    • "text"或'text':代表字符串
    • 数组:数组元素用英文字符隔开。eg:{'keli','zhangsan','lisi','wangwu'}
    • 数值直接量:包括整数、小数、科学计数法
    • 十六进制数:以0x开头
    • 八进制数:以0o开头
    • 二进制数:以0b开头
  • 相关阅读:
    如何得到数据绑定的树节点的父节点
    ImageBrush中的图片如何加载到到MemoryStream
    C#中动态加载和卸载DLL
    SetProcessWorkingSetSize减少内存占用
    wpf中如何改变Listbox选中项的颜色
    怎样把Visual Studio与Perforce关联起来
    在WPF里面如何使用FolderBrowserDialog
    关于WPF的ComboBox中Items太多而导致加载过慢的问题(转载)
    得到系统中所有正打开的文件
    把ResourceDictionary保存为文件,从外部xaml文件加载ResourceDictionary
  • 原文地址:https://www.cnblogs.com/mukekeheart/p/7388734.html
Copyright © 2011-2022 走看看