很多初學者都很少接觸NSPredicate,即使接觸了NSPredicate 也不太了解NSPredicate的使用場景。此處根據我的使用,簡單介紹一下NSPredicate的使用場景:
NSPredicate 主要是用來查詢、條件過濾;
最常用的場景就是在自定義的數據模型對象
中根據條件來查詢相關信息,例如在手機通訊錄中根據個人信息的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現有任意多的字符串,結尾必須為abc+任意一個字符
MATCHES : 字符串是否匹配指定的正則表達式;正則表達式功能強大,但是執行效率低。能用謂詞表達式的就不要用正則表達式
注意:字符串比較運算符默認區分大小寫和重音符號
1.如果希望字符串比較運算符不區分大小寫,可以再運算符后添加[c]
2.如果希望字符串比較運算符不區分重音符號,可以再運算符后添加[d]
一般都是在運算符后面添加[cd],代表不區分大小寫和重音符號
集合操作相關的運算符
ANY 、SOME :集合中任意一個元素滿足條件,返回YES
ALL :集合中多有元素滿足條件,返回YES
NONE :集合中任何元素不滿足條件,返回YES
IN :左邊的表達式(值) 在右邊的集合中存在,返回YES
array[index] : 返回數組index索引處的元素
array[FIRST] : 返回數組第一個元素
array[LAST] : 返回數組最后一個元素
array[SIZE] : 返回數組元素個數
謂詞表達式中的直接量
FALSE、NO : 邏輯假
TRUE、YES : 邏輯真
NULL、NIL : 空值
SELF :被判斷的對象本身
"text"('text') : 字符串
數組:數組元素以英文逗號隔開
數值直接量:整數、小數、科學技術法
各進制數: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字符串來創建一個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)
//根據謂詞條件過濾數組,返回符合條件的元素組成的新數組
- (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate; // evaluate a predicate against an array of objects and return a filtered array
@end
@interface NSMutableArray<ObjectType> (NSPredicateSupport)
//根據謂詞條件過濾數組,去掉數組中不符合條件的的元素
- (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 的占位符參數
- 通過使用占位符,在謂詞表達式中使用變量
- %K : 動態傳入屬性名
- %@ : 動態設置屬性值
- $SUBSTR : 一個動態變化的值,可以通過它動態改變比較條件
//設置NSPredict 中的可變參數,并計算結果
- (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 的可變參數,返回一個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