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 }
3、谓词本身就代表了一个逻辑条件,计算谓词的结果就返回了BOOL类型的值,谓词一个常用的功能就说对集合进行过滤。当程序使用谓词对集合元素进行过滤时,程序会自动遍历集合元素,并根据集合元素计算谓词的值,只有根据某个集合元素计算谓词并返回YES时,该集合元素才会被保留下来。
NSArray提供了如下方法使用谓词来过滤集合:
NSMutableArray提供了如下方法使用谓词来过滤集合:
NSSet提供如下方法使用谓词进行过滤集合:
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 }
4、在前面的程序中使用谓词的对象总是固定的,总是用指定对象的固定属性与固定的值进行比较,如果符合条件,则返回YES,否则返回NO。有时候我们需要在谓词表达式中使用变量,则可以考虑在谓词表达式中使用占位符参数,在谓词表达式中支持以下两个占位符参数:
如果谓词中由占位符参数,则需要经过两步来计算谓词的结果:
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 }
1、基本比较运算符:=、==(是否相等);>=、=>(左边是否大于或等于右边);<=、=<(左边是否小于或等于右边);>(左边是否大于右边);<(左边是否小于右边);!=、<>(不等于);BETWEEN(必须满足表达式 BETWEEN{下限,上限} 的格式,在范围内左右取等号)。
2、基本逻辑运算符:
3、字符串比较运算符:
上述方法都是区分大小写的,如果要不区分大小写和重音符号,则可以在运算符后面使用[c]、[d]选项,其中[c]指定不区分大小写,[d]指定不区分重音符号。eg:“name BEGINSWITH[c][d] fkja”,则不管name值是FKJava还是fkjava都将返回YES。
4、操作集合的运算符:
5、直接量:
在谓词表达式中,使用双引号和单引号的效果是一样的。但是单引号只能用单引号结束,不能混用。