iOS谓词

简介: iOS谓词

在编写Objective-C程序时,经常需要获取一个对象的集合,并通过某些已知条件计算该集合的值。这时需要保留符合某个条件的对象,删除那些不满足条件的对象。从而提取一些有意义的对象,这便是谓词的作用。


在Cocoa中提供了一个NSpredicate的类,该类的返回值是一个数组,它用于制定过滤器的条件,例如:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 28"];
}


上述代码创建了一个NSpredicate对象,描述的条件是:@"age > 28",即年龄大于28。通过对象描述所需条件,从而通过谓词对每个对象进行筛选。


本节将详细讲解Objective-C谓词的基本知识和具体用法。


创建谓词



可以通过NSPredicate类来创建谓词,具体格式如下所示。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == 'Herbie'"];


如果谓词串中的文本块未被引用,则被看做是键路径,即需要用引号表明是字符串(单引号、双引号均可)。键路径可以在后台包含许多强大的功能。

计算谓词的格式如下所示。

BOOL match = [predicate evaluateWithObject:car];


它让谓词通过某个对象来计算自己的值,给出BOOL值。下面的实例创建了一个谓词,并用指定的对象计算了谓词的值。


实例文件main.m的具体实现代码如下所示。

//创建谓词,要求name以s开头
NSPredicate *pred = [NSPredicate predicateWithFormat:@"name like 's*'"];
FKUser *user1 = [[FKUser alloc]initWithName:@"sun" pass:@"123"];
//对user1对象使用谓词执行判断
BOOL result1 = [pred evaluateWithObject:user1];
NSLog(@"user1的name是否以s开头:%d",result1);
//对user2对象使用谓词执行判断
FKUser *user2 = [[FKUser alloc]initWithName:@"bai" pass:@"563"];
BOOL result2 = [pred evaluateWithObject:user2];
NSLog(@"user2的name是否以s开头:%d",result2);


执行后输出:

2021-07-21 10:39:27.882763+0800 谓词[12847:2010374] user1的name是否以s开头:1
2021-07-21 10:39:27.883336+0800 谓词[12847:2010374] user2的name是否以s开头:0


用谓词过滤集合



在Objective-C程序中,filteredArrayUsingPredicate是NSArray数组的一种类别方法,能够循环过滤数组中的内容,可以将值为YES的对象累积放到结果数组中并返回。下面的实例演示了使用谓词过滤集合的过程。


实例文件main.m的具体实现代码如下所示。

NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:50], [NSNumber numberWithInt:42], [NSNumber numberWithInt:20], [NSNumber numberWithInt:64], [NSNumber numberWithInt:56], nil];
//创建谓词,要求该对象自身的值大于50
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF > 50"];
//使用谓词执行过滤,过滤出值大于50的集合元素
[array filterUsingPredicate:pred1];
NSLog(@"值大于50的元素:%@",array);
NSSet *set = [NSSet setWithObjects:[[FKUser alloc]initWithName:@"AABB" pass:@"343"], [[FKUser alloc]initWithName:@"BB" pass:@"231"], [[FKUser alloc]initWithName:@"CC" pass:@"659"], [[FKUser alloc]initWithName:@"DD" pass:@"743"], [[FKUser alloc]initWithName:@"EE" pass:@"985"], nil];
//创建谓词,要求该对象的name值中包含'BB'
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'BB'"];
//执行过滤,过滤后集合只剩下两个元素
NSSet *newSet = [set filteredSetUsingPredicate:pred2];
NSLog(@"%@", newSet);
NSArray *array1 = [newSet allObjects];
for (FKUser *user in array1) {
    NSLog(@"%@ %@", user.name, user.pass);
}


执行上述代码后会输出:

2021-07-21 11:07:14.700935+0800 谓词[13820:2032977] 值大于50的元素:(
    64,
    56
)
2021-07-21 11:07:14.702254+0800 谓词[13820:2032977] {(
    <FKUser: 0x600000804360>,
    <FKUser: 0x600000804380>
)}
2021-07-21 11:07:14.702437+0800 谓词[13820:2032977] AABB 343
2021-07-21 11:07:14.702537+0800 谓词[13820:2032977] BB 231


在谓词中使用格式说明符



在谓词中可以使用格式说明符,通过%d和%@可以插入数值和字符串,使用%K表示key。在谓词中还可以引入变量名,用$设置类似环境变量的值,例如:


@"name == $NAME"这样可以再用predicateWithSubstitutionVariables调用来构造新的谓词(键/值字典),其中键是变量名,值是要插入的内容。但是这种情况下,不能把变量当成键路径,只能用作值。


下面的实例演示了在谓词中使用格式说明符的过程。

实例文件main.m的具体实现代码如下所示。

NSSet *set = [NSSet setWithObjects:[[FKUser alloc]initWithName:@"AABB" pass:@"343"], [[FKUser alloc]initWithName:@"BB" pass:@"231"], [[FKUser alloc]initWithName:@"CC" pass:@"659"], [[FKUser alloc]initWithName:@"DD" pass:@"743"], [[FKUser alloc]initWithName:@"EE" pass:@"598"], nil];
NSString *proPath = @"name";
NSString *value = @"BB";
//创建谓词,该谓词中包含了两个占位符
//后面的两个变量用于为占位符设置参数值
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", proPath, value];
//执行过滤,过滤后的集合只剩下两个元素
NSSet *newSet = [set filteredSetUsingPredicate:pred];
NSArray *array = [newSet allObjects];
for (FKUser *user in array) {
    NSLog(@"%@ %@", user.name, user.pass);
}
//创建谓词,该谓词表达式中使用%K占位符,该占位符使用pass代替
//要求被比较对象的pass包含$SUBSTR子串
NSPredicate *predTemplate = [NSPredicate predicateWithFormat:@"%K CONTAINS $SUBSTR", @"pass"];
//使用NSDictionary指定SUBSTR为'43'
NSPredicate *pred1 = [predTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObjectsAndKeys:@"43", @"SUBSTR", nil]];
//执行过滤,过滤后的集合只剩下两个元素
NSSet *newSet1 = [set filteredSetUsingPredicate:pred1];
NSArray *array1 = [newSet1 allObjects];
for (FKUser *user in array1) {
    NSLog(@"%@ %@", user.name, user.pass);
}
//使用NSDictionary将SUBSTR的值指定为'59'
NSPredicate *pred2 = [predTemplate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObjectsAndKeys:@"59", @"SUBSTR", nil]];
//执行过滤,过滤后的集合只剩下两个元素
NSSet *newSet2 = [set filteredSetUsingPredicate:pred2];
NSArray *array2 = [newSet2 allObjects];
for (FKUser *user in array2) {
    NSLog(@"%@ %@", user.name, user.pass);
}


执行后将会输出:

2021-07-21 13:50:56.613031+0800 谓词[17663:2122598] BB 231
2021-07-21 13:50:56.614223+0800 谓词[17663:2122598] AABB 343
2021-07-21 13:50:56.614813+0800 谓词[17663:2122598] AABB 343
2021-07-21 13:50:56.614957+0800 谓词[17663:2122598] DD 743
2021-07-21 13:50:56.615292+0800 谓词[17663:2122598] EE 598
2021-07-21 13:50:56.615575+0800 谓词[17663:2122598] CC 659


摘自《Objective-C 应用开发全程实录》

目录
相关文章
|
机器学习/深度学习 API iOS开发
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(一)
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(一)
141 0
|
存储 自然语言处理 Java
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(二)
【IOS 开发】Objective-C Foundation 框架 -- 字符串 | 日期 | 对象复制 | NSArray | NSSet | NSDictionary | 谓词(二)
218 0
|
SQL iOS开发
30分钟摸透iOS中谓词NSPredicate的来龙去脉(二)
30分钟摸透iOS中谓词NSPredicate的来龙去脉
193 0
|
iOS开发
30分钟摸透iOS中谓词NSPredicate的来龙去脉(一)
30分钟摸透iOS中谓词NSPredicate的来龙去脉
214 0
|
iOS开发 SQL 机器学习/深度学习
|
iOS开发 存储
[IOS开发]搜索用谓词NSPredicate
<p style="margin-top:0px; margin-bottom:5px; padding-top:0px; padding-bottom:0px; border:0px; list-style:none; word-wrap:normal; word-break:normal; line-height:21px; color:rgb(70,70,70); font-fami
1426 0
|
iOS开发
IOS之谓词的用法
<span style="background-color:rgb(255,255,255)"><span style="color:#FD0F3C; word-wrap:normal; word-break:normal; line-height:21px; font-family:simsun; font-size:14px">谓词就是一个判断的类</span><br style="c
1045 0
|
SQL 机器学习/深度学习 Shell
IOS谓词--NSPredicate
<h4 style="margin:0px; padding:0px; color:rgb(51,51,51); font-family:Arial; font-size:14.44444465637207px; line-height:26px"> <span style="font-size:14.44444465637207px">Cocoa 提供了NSPredicate 用于指定
1063 0
|
iOS开发
IOS谓词--NSPredicate 和array
<p style="margin-top:0px; margin-bottom:0px; font-size:14px; font-family:Menlo">        NSArray *array = [NSArray array];</p> <p style="margin-top:0px; margin-bottom:0px; font-size:14px; font-fam
940 0
|
iOS开发
iOS 中谓词的研究心得
iOS 中谓词的研究心得 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
974 0