- NSPredicate可用于检索查询,其实就是一个过滤器
- iOS中的Predicate 即谓词逻辑, 和数据库的SQL语句具有相似性。都是从数据堆中根据条件进行筛选
常用的方法:
NSPredicate *predicate = [NSPredicate predicateWithFormat:<#(nonnull NSString *), ...#>];
1. 关系比较、判断
- =、==:判断两个表达式是否相等,在谓词中=和==都是相同的意思。属于判断条件,不是赋值
NSNumber *number = @(666);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 666"];
if ([predicate evaluateWithObject:number]) {
NSLog(@"number->%@", number); // number->666
}
- =>,>=:判断左边表达式的值是否大于或等于右边表达式的值
NSNumber *number = @(666);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF >= 6"];
if ([predicate evaluateWithObject:number]) {
NSLog(@"number->%@", number); // number->666
}else {
NSLog(@"没有符合条件的值");
}
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF >= 999"];
if ([predicate1 evaluateWithObject:number]) {
NSLog(@"number->%@", number);
}else {
NSLog(@"没有符合条件的值"); // 没有符合条件的值
}
- =<,<=:判断右边表达式的值是否小于或等于右边表达式的值
- >:判断左边表达式的值是否大于右边表达式的值
- <:判断左边表达式的值是否小于右边表达式的值
- !=、<>:判断两个表达式不相等
NSNumber *number = @(666);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF <> 999"];
if ([predicate evaluateWithObject:number]) {
NSLog(@"number->%@", number); // number->666
}else {
NSLog(@"没有符合条件的值");
}
- BETWEEN{a,b}:判断是否在[a, b]这个区间范围(包含a、b),相当于(表达式:a<= 值 <=b),要求该表达式必须大于或等于下限,并小于或等于上限
NSNumber *number = @3;
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"self BETWEEN {1,5}"];
if ([pre1 evaluateWithObject:number]) {
NSLog(@"number->%@", number); // number->3
} else {
NSLog(@"不符合条件");
}
2. 逻辑运算符
- AND、&&:逻辑与,要求两个表达式的值都为YES时,结果才为YES
NSArray *array = @[@1, @2, @3, @4, @5, @6, @7, @8];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 6"];
NSArray *filterArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filterArray->%@", filterArray); // [3, 4, 5]
- OR、||:逻辑或,要求其中一个表达式为YES时,结果就是YES
NSArray *array = @[@1, @2, @3, @4, @5, @6, @7, @8];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 6 or SELF < 2"];
NSArray *filterArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filterArray->%@", filterArray); // [1, 7, 8]
- NOT、 !:逻辑非,对原有的表达式取反
3. 字符串相关
字符串比较都是区分大小写和重音符号的,如果需要字符串比较运算不区分大小写和重音符号,要在这些运算符后使用[c],[d]选项。
[c]:忽略大小写
[d]:忽略重音符号
[cd]:既不区分大小写,也不区分发音符号
- BEGINSWITH:检查某个字符串是否以指定的字符串开头(如判断字符串是否以a开头:BEGINSWITH 'a')
NSArray *array = @[@"abcd",@"bbce",@"agyy"];
NSString *str = @"a";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self BEGINSWITH %@",str];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"result->%@",result); // [abcd,agyy]
NSArray *array1 = @[@"老王",@"牛王",@"王老湿"];
NSString *str1 = @"王";
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"self ENDSWITH %@",str1];
NSArray *result1 = [array1 filteredArrayUsingPredicate:predicate1];
NSLog(@"result1->%@",result1); // [老王,牛王]
- ENDSWITH:检查某个字符串是否以指定的字符串结尾
NSArray *array = @[@"abcd",@"bbced",@"agyy"];
NSString *str = @"d";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self ENDSWITH %@",str];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"result->%@",result); // [abcd,bbced]
- CONTAINS:检查某个字符串是否包含指定的字符串
// SELF CONTAINS:表示自身包含
// [c]:忽略大小写,[d]:忽略重音符号,[cd]既不区分大小写,也不区分发音符号
// CONTAINS(包含):数组中是否包含某个内容
// 1. 获取包含某个字符串的数组中元素
NSArray *arr1 = @[@"abcd",@"我是谁",@"美丽的传说"];
NSString *content = @"传说";
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"self contains [cd] %@",content]; // 不区分大小写和发音符
NSArray *result1 = [arr1 filteredArrayUsingPredicate:pre1];
NSLog(@"result1 -> %@",result1); // @[@"美丽的传说"]
NSArray *arr2 = @[@"NiuBi", @"laodao", @"pinseng", @"ChiDaoDeDiaoBi", @"MoMo"];
NSString *str2 = @"niu";
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",str2]; // 区分大小写
NSArray *result2 = [arr2 filteredArrayUsingPredicate:pred2];
NSLog(@"result2 -> %@",result2); // nil
NSString *str3 = @"LaoDao";
NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"SELF CONTAINS [c] %@",str3]; // 不区分大小写
NSArray *result3 = [arr2 filteredArrayUsingPredicate:pred3];
NSLog(@"result3 -> %@",result3); // @[@"laodao"]
// 2. 根据模型属性查找模型数组中是否有某个元素
CCPredicateModel *model1 = [[CCPredicateModel alloc] init];
model1.name = @"老王";
model1.content = @"做事不合规矩";
CCPredicateModel *model2 = [[CCPredicateModel alloc] init];
model2.name = @"LaoWangDeGe";
model2.content = @"HenNiuBi";
NSArray *arr4 = [[NSArray alloc] initWithObjects:model1,model2, nil];
NSString *str4 = @"老";
NSPredicate *pred4 = [NSPredicate predicateWithFormat:@"name CONTAINS %@",str4];
NSArray *result4 = [arr4 filteredArrayUsingPredicate:pred4];
NSLog(@"result4 -> %@",result4); // result4 -> model1
-
LIKE:通配符,检查某个字符串是否匹配指定的字符串模板。
"?"代表一个字符;"*"代表任意多个字符
NSArray *array = @[@{@"name" : @"abcdefghk"}, @{@"name" : @"azbcefghlkmnp"}];
NSString *str1 = @"*km*";
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"name LIKE %@", str1];
NSArray *filterArray1 = [array filteredArrayUsingPredicate:predicate1];
NSLog(@"filterArray1->%@", filterArray1); // {name:azbcefghlkmnp}
NSString *str2 = @"??c*";
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"name LIKE %@", str2];
NSArray *filterArray2 = [array filteredArrayUsingPredicate:predicate2];
NSLog(@"filterArray2->%@", filterArray2); // {name:abcdefghk}
-
MATCHES:检查某个字符串是否匹配指定的正则表达式
[正则表达式相关内容:] (https://www.jianshu.com/p/9b4bc550dff7)
// 检测字符串中是否有特殊字符
NSString *regex1 = @"[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]+";
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
NSString *str1 = @"【";
if ([pred1 evaluateWithObject:str1]) {
NSLog(@"str1->%@",str1); // @"【"
}
// 只能包含数字或英文
NSString *regex2 = @"^[a-z0-9A-Z]*$";
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
NSString *str2 = @"CK99";
if ([pred2 evaluateWithObject:str2]) {
NSLog(@"str2->%@",str2); // CK99
}
4. 数组与Predicate结合使用
- ANY、SOME:集合中任意一个元素满足条件,就返回YES
- ALL:集合中所有元素都满足条件,才返回YES
- NONE:集合中没有任何元素满足条件就返回YES。如:NONE num < 5,表示元素符合num >= 5时,才返回YES
- IN:等价于SQL语句中的IN运算符,只有当左边表达式或值出现在右边的集合中才会返回YES
// 1.过滤字典数组
NSArray *dicts = @[@{@"name" : @"皮皮"},@{@"name" : @"老王"}, @{@"name" : @"小井"}];
NSPredicate *pre1 = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[evaluatedObject valueForKey:@"name"] isEqualToString:@"老王"];
}];
NSArray *result1 = [dicts filteredArrayUsingPredicate:pre1];
NSLog(@"result1->%@",result1); // @[@{name:老王}]
// 2.过滤数组中的字符串
NSArray *strs = @[@"皮皮", @"老王", @"小井"];
NSPredicate *pre2 = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
if ([evaluatedObject isEqual:@"皮皮"]) {
return YES;
}
return NO;
}];
NSArray *result2 = [strs filteredArrayUsingPredicate:pre2];
NSLog(@"result2 -> %@",result2); // @[@"皮皮"]
// 3.过滤数组中元素的长度
NSArray *arr3 = @[@"NiuBi", @"laodao", @"pinseng", @"ChiDaoDeDiaoBi", @"MoMo"];
NSPredicate *pre3 = [NSPredicate predicateWithFormat:@"length > 5"];
NSArray *result3 = [arr3 filteredArrayUsingPredicate:pre3];
NSLog(@"result3 -> %@", result3); // @["laodao", "pinseng", "ChiDaoDeDiaoBi"]
// 4.筛选array1与array2相同的元素:其中SELF指向filteredArrayUsingPredicate的调用者
NSArray *array1 = @[@1,@2,@3,@4,@5,@6,@7,@8];
NSArray *array2 = @[@1,@5,@9];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF in %@",array2];
NSArray *result = [array1 filteredArrayUsingPredicate:predicate];
NSLog(@"result->%@", result); // @1,@5
// 筛选array1中array2不存在的元素
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)",array2];
NSArray *result1 = [array1 filteredArrayUsingPredicate:predicate1];
NSLog(@"result1->%@", result1); // @2,@3,@4,@6,@7,@8
5. 在谓词中使用占位符
在谓词表达式中使用变量,那么我们需要了解下列两种占位符:相当于变量名与变量值
- %K:用于动态传入属性名
- %@:用于动态设置属性值
网友评论