很多初學者都很少接觸NSPredicate壁肋,即使接觸了NSPredicate 也不太了解NSPredicate的使用場景伯复。此處根據我的使用,簡單介紹一下NSPredicate的使用場景:
NSPredicate 主要是用來查詢辜限、條件過濾;
最常用的場景就是在自定義的數(shù)據模型對象
中根據條件來查詢相關信息遵蚜,例如在手機通訊錄中根據個人信息的Model所包含的name屬性坎匿,來進行搜索
** 簡言之** NSPredicate可以判斷某個對象的某一個屬性是否符合某一條件
1. NSPredict簡單說明
- NSPredict 謂詞可以通過定義一個邏輯條件,來搜索查詢蚁廓、過濾信息
- NSPredict主要包含三個子類:NSComparisonPredicate宿亡、NSCompoundPredicate、NSExpression
2. NSPredict 表達式
在介紹NSPredict的使用之前纳令,我們必須先要了解如何正確的書寫謂詞表達式
比較運算符
= 挽荠、 == :判斷兩個表達式是否相等
>= 、=>: 左側表達式是否大于或等于右側表達式
<= 平绩、 =< :左側表達式是否小于或等于右側表達式
> 圈匆、< :左側表達式是否大于、小于右側表達式
捏雌!= 跃赚、<>: 兩個表達式是否不相等
BETWEEN :”表達式 BEYWEEN {最小值,最大值}“ 性湿,表達式必須大于等于最小值或小于等于最大值
邏輯運算符
AND纬傲、&& :兩個表達式都為真是,結果為真肤频;有假則結果為假
OR叹括、|| :兩個表達式有一個結果為真,結果為真宵荒;同為假汁雷,則結果為假
NOT 、报咳!: 表達式結果取反
字符串
比較運算符BEGINSWITH :字符串是否以某一子字符串開頭
ENDSWITH : 字符串是否以某一子字符串結尾
CONTAINS :字符串是否包含某一子字符串
-
LIKE :字符串是否匹配指定的字符串
模板
- 模板中可以包含通配符: *(任意多個字符)侠讯、?(一個字符)
- title LIKE *abc? :title現(xiàn)有任意多的字符串暑刃,結尾必須為abc+任意一個字符
MATCHES : 字符串是否匹配指定的正則表達式厢漩;正則表達式功能強大,但是執(zhí)行效率低岩臣。能用謂詞表達式的就不要用正則表達式
注意:字符串比較運算符默認區(qū)分大小寫和重音符號
1.如果希望字符串比較運算符不區(qū)分大小寫溜嗜,可以再運算符后添加[c]
2.如果希望字符串比較運算符不區(qū)分重音符號柴底,可以再運算符后添加[d]
一般都是在運算符后面添加[cd],代表不區(qū)分大小寫和重音符號
集合操作相關的運算符
ANY 、SOME :集合中任意一個元素滿足條件粱胜,返回YES
ALL :集合中多有元素滿足條件,返回YES
NONE :集合中任何元素不滿足條件狐树,返回YES
IN :左邊的表達式(值) 在右邊的集合中存在焙压,返回YES
array[index] : 返回數(shù)組index索引處的元素
array[FIRST] : 返回數(shù)組第一個元素
array[LAST] : 返回數(shù)組最后一個元素
array[SIZE] : 返回數(shù)組元素個數(shù)
謂詞表達式中的直接量
FALSE、NO : 邏輯假
TRUE抑钟、YES : 邏輯真
NULL涯曲、NIL : 空值
SELF :被判斷的對象本身
"text"('text') : 字符串
數(shù)組:數(shù)組元素以英文逗號隔開
數(shù)值直接量:整數(shù)、小數(shù)在塔、科學技術法
各進制數(shù):0x(十六進制)幻件、0o(八進制)、0b(二進制)
注意:謂詞表達式中" "與' '效果相同蛔溃,但是“ ”與‘ ’應該匹配保留字:大寫單詞是保留字
MATCHES绰沥、CONTAINS、BEGINSWITH贺待、ENDSWIHT徽曲、BETWEEN、NULL麸塞、NIL秃臣、SELF、AND哪工、OR奥此、IN、NOT雁比、ALL稚虎、ANY、SOME偎捎、NONE祥绞、LIKE、CASEINSENSITIVE鸭限、CI蜕径、TRUE、YES败京、FALSE兜喻、NO、FIRST赡麦、LAST朴皆、SIZE帕识、ANYKEY、SUBQUERY遂铡、CAST肮疗、TRUEPREDICATE、FALSEOREDICATE
2. NSPredict定義
//以一個NSPredict字符串來創(chuàng)建一個NSPredict對象
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat argumentArray:(nullable NSArray *)arguments;
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat arguments:(va_list)argList;
//通過一個對象來計算謂詞的結果 真/假
- (BOOL)evaluateWithObject:(nullable id)object;
- 示例代碼
ZZYPerson * person1 = [[ZZYPerson alloc]initWithName:@"zhang san" Age:@"21"];
NSPredicate * pred1 = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@",@"san"];
NSPredicate * pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] 'san'"];
//注意第二種寫法要將字符串用單引號包起來
BOOL isHave = [pred1 evaluateWithObject:person1];
NSLog(@"%d",isHave); //輸出值為:1
NSLog(@"%@---%@",person1.name,person1.age);//輸出值為:zhang san---21
** 注意 **上述代碼中pred2中的寫法扒接,字符串要用單引號括起來(比如sql語句中的字符串也要包含起來)
3. NSPredict 過濾查找集合元素
- NSPredict 本質上就是一個邏輯條件伪货,NSPredict 運算的結果就是一個BOOL值
- NSPredict 一個比較常用的功能就是
對集合元素的過濾
; 自動遍歷集合元素------>根據元素判斷 NSPredict 的結果------>結果為YES時,集合元素保存 - 注意謂詞過濾不可變集合钾怔,結果返回符合條件的新集合碱呼;謂詞過濾可變集合,直接將集合中不符合條件的元素去掉
@interface NSArray<ObjectType> (NSPredicateSupport)
//根據謂詞條件過濾數(shù)組宗侦,返回符合條件的元素組成的新數(shù)組
- (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate; // evaluate a predicate against an array of objects and return a filtered array
@end
@interface NSMutableArray<ObjectType> (NSPredicateSupport)
//根據謂詞條件過濾數(shù)組愚臀,去掉數(shù)組中不符合條件的的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate; // evaluate a predicate against an array of objects and filter the mutable array directly
@end
@interface NSSet<ObjectType> (NSPredicateSupport)
////根據謂詞條件過濾集合,返回符合條件的元素組成的新集合
- (NSSet<ObjectType> *)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0); // evaluate a predicate against a set of objects and return a filtered set
@end
@interface NSMutableSet<ObjectType> (NSPredicateSupport)
//根據謂詞條件過濾集合矾利,去掉集合中不符合條件的的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0); // evaluate a predicate against a set of objects and filter the mutable set directly
@end
- 示例代碼
NSArray * array = @[@"libai",@"dufu",@"sushi",@"dumu"];
NSPredicate * pred = [NSPredicate predicateWithFormat:@"SELF like %@",@"du*"];
NSArray * resultArr = [array filteredArrayUsingPredicate:pred];
NSLog(@"%@",resultArr);//輸出值:(
dufu,
dumu
)
NSSet * set = [NSSet setWithObjects:
[[ZZYPerson alloc]initWithName:@"li si" Age:@"25"],
[[ZZYPerson alloc]initWithName:@"zhang san" Age:@"20"],
[[ZZYPerson alloc]initWithName:@"wang wu" Age:@"18"],nil
];
NSPredicate * pred3 = [NSPredicate predicateWithFormat:@"name CONTAINS 'ang'"];
NSSet * resultSet = [set filteredSetUsingPredicate:pred3];
for (ZZYPerson * person in resultSet) {
NSLog(@"%@",person.name);
}
NSArray * array3 = @[[[ZZYPerson alloc]initWithName:@"li si" Age:@"25"],
[[ZZYPerson alloc]initWithName:@"zhang san" Age:@"20"],
[[ZZYPerson alloc]initWithName:@"wang wu" Age:@"18"]];
NSArray * array4 = [array3 filteredArrayUsingPredicate:pred3];
for (ZZYPerson * person in array4) {
NSLog(@"%@",person.name);
}
//輸出值:
zhang san
wang wu
4. NSPredict 的占位符參數(shù)
- 通過使用占位符姑裂,在謂詞表達式中使用變量
- %K : 動態(tài)傳入屬性名
- %@ : 動態(tài)設置屬性值
- $SUBSTR : 一個動態(tài)變化的值,可以通過它動態(tài)改變比較條件
//設置NSPredict 中的可變參數(shù)男旗,并計算結果
- (BOOL)evaluateWithObject:(nullable id)object substitutionVariables:(nullable NSDictionary<NSString *, id> *)bindings NS_AVAILABLE(10_5, 3_0); // single pass evaluation substituting variables from the bindings dictionary for any variable expressions encountered
//設置NSPredict 的可變參數(shù)炭分,返回一個NSPredict 對象
- (instancetype)predicateWithSubstitutionVariables:(NSDictionary<NSString *, id> *)variables; // substitute constant values for variables
- 示例代碼
ZZYPerson * person1 = [[ZZYPerson alloc]initWithName:@"zhang san" Age:@"21"];
ZZYPerson * person2 = [[ZZYPerson alloc]initWithName:@"li si" Age:@"25"];
ZZYPerson * person3 = [[ZZYPerson alloc]initWithName:@"stark" Age:@"11"];
ZZYPerson * person4 = [[ZZYPerson alloc]initWithName:@"sunny" Age:@"30"];
NSArray * array2 = @[person1,person2,person3,person4];
NSString * name = @"age";
NSString * age = @"3";
NSPredicate * changePre1 = [NSPredicate predicateWithFormat:@"%K CONTAINS[cd] %@",name,age];
NSArray * newArray2 = [array2 filteredArrayUsingPredicate:changePre1];
for (ZZYPerson * person in newArray2) {
NSLog(@"newArray2%@----%@",person.name,person.age);
}
//name中包含$SUBSTR的字串
NSPredicate * changePre2 = [NSPredicate predicateWithFormat:@"%K CONTAINS[cd] $SUBSTR",@"name"];
//指定$SUBSTR的值為sun
NSPredicate * newChangePre2 = [changePre2 predicateWithSubstitutionVariables:@{@"SUBSTR":@"sun"}];
NSArray * newArray3 = [array2 filteredArrayUsingPredicate:newChangePre2];
for (ZZYPerson * person in newArray3) {
NSLog(@"newArray3%@----%@",person.name,person.age);
}
NSPredicate * newChangePre3 = [changePre2 predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObjectsAndKeys:@"ang",@"SUBSTR", nil]];
NSArray * newArray4 = [array2 filteredArrayUsingPredicate:newChangePre3];
for (ZZYPerson * person in newArray4) {
NSLog(@"newArray4%@----%@",person.name,person.age);
}
//輸出結果:
2016-06-27 23:07:11.820 ZZYNSPredicate[4540:96427] newArray2sunny----30
2016-06-27 23:07:11.820 ZZYNSPredicate[4540:96427] newArray3sunny----30
2016-06-27 23:07:11.820 ZZYNSPredicate[4540:96427] newArray4zhang san----21