NSPredicate
NSPredicate(謂詞),可以根據定義的模糊查詢條件,對內存對象進行過濾搜索。
基本語法
- 謂詞表達式 : 由表達式、運算符和值構成。
- 值:
FALSE、NO:代表邏輯假
TRUE、YES:代表邏輯真
NULL、NIL:代表空值
SELF:代表正在被判斷的對象自身
"string"或'string':代表字符串
數組:和c中的寫法相同,如:{'one', 'two', 'three'}。
數值:包括證書、小數和科學計數法表示的形式
十六進制數:0x開頭的數字
八進制:0o開頭的數字
二進制:0b開頭的數字-
運算符:
常見用途
1.使用謂詞進行正則匹配,例如:
匹配手機號
- (BOOL)checkPhoneNumber:(NSString *)phoneNumber
{
NSString *regex = @"^[1][3-8]\\d{9}$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [pred evaluateWithObject:phoneNumber];
}
驗證郵箱
+ (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];
}
ps:使用正則匹配時,更推薦使用NSRegularExpression而不是NSPredicate,因為NSPredicate對某些表達式的匹配結果并不盡如人意。
正則相關:正則表達式在IOS中的應用
2.使用謂詞過濾集合
- NSArray提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSArray集合,返回符合條件的元素組成的新集合
- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate;
- NSMutableArray提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSMutableArray,剔除集合中不符合條件的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate;
- NSSet提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSSet集合,返回符合條件的元素組成的新集合
- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate;
- NSMutableSet提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSMutableSet,剔除集合中不符合條件的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate;
- NSOrderedSet提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSOrderedSet集合,返回符合條件的元素組成的新集合
- (NSOrderedSet<ObjectType> *)filteredOrderedSetUsingPredicate:(NSPredicate *)p;
- NSMutableOrderedSet提供了如下方法使用謂詞來過濾集合
//使用指定的謂詞過濾NSMutableOrderedSet,剔除集合中不符合條件的元素
- (void)filterUsingPredicate:(NSPredicate *)p;
- 以上方法都可以在NSPredicate.h文件中找到。
使用示例:
創建數組,數組中的元素包含name和age兩個屬性
NSArray *persons = ...
定義謂詞對象,謂詞對象中包含了過濾條件
(過濾條件中,使用self.name和直接用name的效果一樣)
//age小于30
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<30"];
//查詢name=1的并且age大于40
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name='1' && age>40"];
//name以a開頭的
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'a'"];
//name以ba結尾的
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name ENDSWITH 'ba'"];
//name為1/2/4,或者age為30/40
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN {'1','2','4'} || age IN{30,40}"];
//like 匹配任意多個字符
//name中只要有s字符就滿足條件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '*s*'"];
//?代表一個字符,下面的查詢條件是:name中第二個字符是s的
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '?s'"];
使用謂詞條件過濾數組中的元素,過濾之后返回查詢的結果
NSArray *array = [persons filteredArrayUsingPredicate:predicate];
- 謂詞的表達式中,如果要動態修改條件,可以使用占位符:
在使用時,如果需要拼接屬性名,其占位符為%K(注意大寫)而不是%@,如:
NSString * key = @"age";
int age = 30;
//拼接示例:
[NSPredicate predicateWithFormat:@"%K < %d", key, age];
如果想動態改變判斷的范圍,可以使用$ 開頭的占位符:
//用$AGE進行占位,可以動態修改$對應的值,這里的AGE可以是任意字符串
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < $AGE"];
//修改AGE的值(AGE對應上面的$后的字符串),生成新的NSPredicate對象
NSPredicate *newPredicate = [predicate predicateWithSubstitutionVariables:@{@"AGE":@30}];
//使用newPredicate過濾數組
NSArray *array = [persons filteredArrayUsingPredicate: newPredicate];
PS:個人感覺用字符串拼接的方式設置表達式的自由度更高。