在 iOS 中使用谓词的功能还是非常的实用的,比如我们可以利用它进行本地匹配检索、集合过滤、单个对象条件过滤等。作用很像SQL语句中的 where 条件表达式。那么讲到它就不得不介绍下 Cocoa 框架中提供的 NSPredicate 这个类了,在苹果的 API 文档中开头是这样介绍 NSPredicate 的 :
考虑到我在英语方面的渣5实力,下面这段英文解释翻完字典之后大概意思如下 : (NSPredicate这个类是用于定义逻辑条件和用于限制搜索获取或者内存筛选的。)看完有木有一头雾水,不过没关系,我们接下来一点点来拆分它的作用。
一、聊聊关于谓词的一些语法
案例01:SELF / = / == / > 等比较运算符用法
// 随意创建一个字符串
NSString *testString = @"我只是个码农1";
// 创建谓词对象 并 设置过滤条件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = '我只是个码农'"];
// 只有内容为 我只是个码农 才返回YES
BOOL isResult = [predicate evaluateWithObject:testString];
if (isResult) NSLog(@"这个字符串内容是:我只是个码农");
// 01 - 上面的 SELF 代表的是被过滤对象本身
// 02 - 上面的 =/== 号为比较运算符
// 03 同理 >= / => 代表 左边表达式值大于等于右边表达式的值
// 04 同理 <= / =< 代表 左边表达式值小于等于右边表达式的值
// 05 同理 < / > 代表 左边表达式值小于或大于右边表达式的值
// 06 同理 != / <> 代表 左边表达式值不等于右边表达式的值
案例02:BEWTEEN 保留字用法
// BETWEEN 的意思是是否在某个区间 经常与{}结合使用
NSNumber *testNum = @888;
// 创建谓词对象
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100,1000}"];
// 判断是否在100~1000之间的数
if ([predicate evaluateWithObject:testNum]) {
NSLog(@"符合条件");
} else {
NSLog(@"不符合条件");
}
案例03:AND 、&& 等逻辑运算符用法
// 创建存有NSNumber对象的数组
NSArray *testArr = @[@2,@10,@5,@8,@0];
// 创建谓词对象
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 3 AND SELF < 9"];
// 按照条件过滤后新的数组
NSArray *newArr = [testArr filteredArrayUsingPredicate:predicate];
// 打印
NSLog(@"%@", newArr);
/**
AND / && 逻辑与
OR / || 逻辑或
NOT / ! 非
*/
打印结果 :
2017-01-29 01:27:01.214 NSPredicateDemo[23157:813914] (
5,
8
)
案例04:BEGINSWITH 、ENDSWITH、CONTAINS、LIKE、MATCHES 等字符串比较运算符用法
// BEGINSWITH 相当于字符串方法中的 - (BOOL)hasPrefix:(NSString *)str;
NSString *testString = @"https://www.baidu.com";
NSString *flagString = @"https://";
// 创建谓词对象
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH %@", flagString];
// 判断
if ([pre evaluateWithObject:testString]) {
NSLog(@"是一个安全的网址(URL)");
} else {
NSLog(@"不是一个安全的网址(URL)");
}
// 01 同理 ENDSWITH 相当于字符串方法中的 - (BOOL)hasSuffix:(NSString *)str;
// 02 CONTAINS 检查某个字符串是否包含指定的字符串
// 03 LIKE:检查某个字符串是否匹配指定的字符串模板 常与 * 和 ? 搭配使用 ;
// 其中 ? 号表示一个字符 ; * 号表示任意通配字符
// 例如 : @"name LIKE '*loser*'" 代表如果指定字符串包含 loser 则返回 YES
// @"name LIKE '?loser'" 代表如果指定字符串第 2-3-4-5-6 个字符分别是loser 则返回 YES
案例05 : 利用上面的字符串比较运算符 可以做到内存信息匹配搜 ; 需要看Demo的话可以去我的GitHub仓库 :
https://github.com/IMLoser/NSPredicate
案例06 : MATCHES 可以使得谓词与正则表达式一起使用 (检查某个字符串是否匹配指定的正则表达式)
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *emailStr = @"imloser@163.com";
if ([self validateEmail:emailStr]) {
NSLog(@"邮箱格式正确!");
} else {
NSLog(@"邮箱格式不正确!");
}
}
// 验证邮箱是否合法
- (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];
}
@end
/**
注:字符串比较都是区分大小写和重音符号的。如:café和cafe是不一样的,Cafe和cafe也是不一样的。如果希望字符串比较运算不区分大小写和重音符号,请在这些运算符后使用[c],[d]选项。其中[c]是不区分大小写,[d]是不区分重音符号,其写在字符串比较运算符之后,比如:name LIKE[cd] 'cafe',那么不论name是cafe、Cafe还是café上面的表达式都会返回YES。
*/
案例07 : 集合运算符
/**
ANY、SOME:集合中任意一个元素满足条件,就返回YES。
ALL:集合中所有元素都满足条件,才返回YES。
NONE:集合中没有任何元素满足条件就返回YES。如:NONE person.age < 18,表示person集合中所有元素的age>=18时,才返回YES。
IN:等价于SQL语句中的IN运算符,只有当左边表达式或值出现在右边的集合中才会返回YES。
*/
// 案例 :将arr01中与arr02里面相同的元素剔除
NSArray *arr01 = @[@"陈冠希",@"刘德华",@"谢霆锋",@"张柏芝"];
NSArray *arr02 = @[@"刘德华",@"谢霆锋"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", arr02];
NSArray *newArr = [arr01 filteredArrayUsingPredicate:pre];
for (id name in newArr) {
NSLog(@"newArr - %@", name);
}
2017-01-30 20:39:55.409 NSPredicateDemo[30134:1069877] newArr - 陈冠希
2017-01-30 20:39:55.410 NSPredicateDemo[30134:1069877] newArr - 张柏芝
/**
array[index]:返回array数组中index索引处的元素
array[FIRST]:返回array数组中第一个元素
array[LAST]:返回array数组中最后一个元素
array[SIZE]:返回array数组中元素的个数
*/
案例08 : 谓词中的直接量和保留字
/**
直接量 :
FALSE、NO:代表逻辑假
TRUE、YES:代表逻辑真
NULL、NIL:代表空值
SELF:代表正在被判断的对象自身
"string"或'string':代表字符串
数组:和c中的写法相同,如:{'one', 'two', 'three'}。
数值:包括证书、小数和科学计数法表示的形式
十六进制数:0x开头的数字
八进制:0o开头的数字
二进制:0b开头的数字
*/
/**
谓词中的保留字 : (不区分大小写)
AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、
CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、
NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE
*/