【OC梳理】NSPredicate

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:個人感覺用字符串拼接的方式設置表達式的自由度更高。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容