iOS Foundation框架之謂詞NSPredicate

很多初學者都很少接觸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

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

推薦閱讀更多精彩內容