NSPredicate 的使用

NSPredicate 這個類主要有兩個方面的作用:

  1. 從集合類中過濾數(shù)據(jù)
  2. 和正則表達式進行正則判斷(比方說驗證手機號,郵箱,IP地址是否滿足要求,其實還是過濾數(shù)據(jù))

集合中過濾數(shù)據(jù)

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *age;
@end

@implementation Person

- (NSString *)description {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

@end

#pragma mark -

NSArray *firstNames = @[ @"Alice", @"Bob", @"Charlie", @"Quentin" ];
NSArray *lastNames = @[ @"Smith", @"Jones", @"Smith", @"Alberts" ];
NSArray *ages = @[ @24, @27, @33, @31 ];

NSMutableArray *people = [NSMutableArray array];
[firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    Person *person = [[Person alloc] init];
    person.firstName = firstNames[idx];
    person.lastName = lastNames[idx];
    person.age = ages[idx];
    [people addObject:person];
}]; 
  1. 過濾對象的firstName屬性 firstName = 'Bob',執(zhí)行結(jié)果是獲取 firstName = 'Bob' 的數(shù)組
NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];
NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);
["Bob Jones"]
  1. 過濾對象 age >= 30
NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];
NSLog(@"30's: %@", [people filteredArrayUsingPredicate:thirtiesPredicate]);
["Charlie Smith", "Quentin Alberts"]
  1. 過濾年齡 在 26和30之間的情況
 NSPredicate *agePredicate2 = [NSPredicate predicateWithFormat:@"age BETWEEN {26, 30}"];
 NSLog(@"age2:%@",[people filteredArrayUsingPredicate:agePredicate2]);
    
  1. 過濾年齡在 26 到30 之間,firstName為 'Alice','Bob' 的情況
 NSPredicate *agePredicate4 = [NSPredicate predicateWithFormat:@"SELF.firstName IN {'Alice','Bob'} && SELF.age BETWEEN {26,30} "];
  NSLog(@"age4:%@",[people filteredArrayUsingPredicate:agePredicate4]);

5.過濾firstName 為alice(忽略大小寫和重低音的情況)

 NSPredicate *agePredicate5 = [NSPredicate predicateWithFormat:@"firstName LIKE[cd] 'alice'"];
 NSLog(@"agePredicate5:%@",[people filteredArrayUsingPredicate:agePredicate5]);

一些謂詞

基本比較

=, ==:左邊的表達式和右邊的表達式相等。(謂詞中 = 和 == 一樣的,都是比較,沒有賦值的意思)
=, =>:左邊的表達式大于或者等于右邊的表達式。
<=, =<:左邊的表達式小于等于右邊的表達式。

:左邊的表達式大于右邊的表達式。
<:左邊的表達式小于右邊的表達式。
!=, <>:左邊的表達式不等于右邊的表達式。
BETWEEN:左邊的表達式等于右邊的表達式的值或者介于它們之間。右邊是一個有兩個指定上限和下限的數(shù)值的數(shù)列(指定順序的數(shù)列)。比如,1 BETWEEN { 0 , 33 },或者INPUT BETWEEN {LOWER, $UPPER }。

基本符合謂詞

  • AND, &&:邏輯與.
  • OR, ||:邏輯或.
  • NOT, !:邏輯非.

字符串比較

字符串比較在默認的情況下是區(qū)分大小寫和音調(diào)的。你可以在方括號中用關(guān)鍵字符c和d來修改操作符以相應(yīng)的指定不區(qū)分大小寫和變音符號,比如firstname BEGINSWITH[cd] $FIRST_NAME。

BEGINSWITH:左邊的表達式以右邊的表達式作為開始。
CONTAINS:左邊的表達式包含右邊的表達式。
ENDSWITH:左邊的表達式以右邊的表達式作為結(jié)束。
LIKE:左邊的表達式等于右邊的表達式:?和可作為通配符,其中?匹配1個字符,匹配0個或者多個字符。
MATCHES:左邊的表達式根據(jù)ICU v3(更多內(nèi)容請查看ICU User Guide for Regular Expressions)的regex風(fēng)格比較,等于右邊的表達式。

合計操作

關(guān)系操作

ANY,SOME:指定下列表達式中的任意元素。比如,ANY children.age < 18。(特別要注意的是操作對象必須是集合,比方說數(shù)組套數(shù)組的情況,操作對象就是數(shù)組) 集合中任意一個元素滿足條件,就返回YES

ALL:指定下列表達式中的所有元素。比如,ALL children.age < 18。 集合中所有元素都滿足條件,才返回YES

NONE:指定下列表達式中沒有的元素。比如,NONE children.age < 18。它在邏輯上等于NOT (ANY ...)。 集合中沒有任何元素滿足條件就返回YES。

IN:等于SQL的IN操作,左邊的表達必須出現(xiàn)在右邊指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' } 等價于SQL語句中的IN運算符,只有當(dāng)左邊表達式或值出現(xiàn)在右邊的集合中才會返回YES

數(shù)組操作

array[index]:指定數(shù)組中特定索引處的元素。
array[FIRST]:指定數(shù)組中的第一個元素。
array[LAST]:指定數(shù)組中的最后一個元素。
array[SIZE]:指定數(shù)組的大小。

布爾值謂詞

TRUEPREDICATE:結(jié)果始終為真的謂詞。
FALSEPREDICATE:結(jié)果始終為假的謂詞。

直接量

在謂詞表達式中可以使用如下直接量

FALSE、NO:代表邏輯假
TRUE、YES:代表邏輯真
NULL、NIL:代表空值
SELF:代表正在被判斷的對象自身
"string"或'string':代表字符串
數(shù)組:和c中的寫法相同,如:{'one', 'two', 'three'}。
數(shù)值:包括證書、小數(shù)和科學(xué)計數(shù)法表示的形式
十六進制數(shù):0x開頭的數(shù)字
八進制:0o開頭的數(shù)字
二進制:0b開頭的數(shù)字
3.6.保留字

下列單詞都是保留字(不論大小寫)
AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE
注:雖然大小寫都可以,但是更推薦使用大寫來表示這些保留字

SELF 指的就是要被判斷的謂詞對象。

過濾方面的具體使用

例子1:獲取選中的規(guī)格ID

isSelected

- (NSString *)SpecValIds {
   // 創(chuàng)建謂詞對象
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"isSelected == %d",YES];
   //self.platProductAttributeAndSpecificationDto.ProductSpecificationDtos 為一個數(shù)組
    NSMutableArray *tmparr = [self.platProductAttributeAndSpecificationDto.ProductSpecificationDtos filteredArrayUsingPredicate:predicate];
    // 從數(shù)組中拿到對象,對這個對象的id進行去重,并且把 id 放到一個數(shù)組中進行返回
    NSArray *editReturnedModeltmparr = [tmparr valueForKeyPath:@"@distinctUnionOfObjects.id"];//
   //  NSString iOS 將數(shù)組中的元素用符號拼接字符串的方法
    NSString *string = [editReturnedModeltmparr componentsJoinedByString:@","];
    return string;
}

例子2:數(shù)據(jù)的過濾,城市搜索

一般的城市搜索,都是支持字母拼寫和漢字搜索的。
可以使用謂詞,也可以不使用謂詞。

方式一,不使用謂詞

+ (NSArray *)searchcityModelsWithSeatchText:(NSString *)searchText{
    NSMutableArray *array = [NSMutableArray array];
    //拼音轉(zhuǎn)化為大寫
    searchText = [searchText uppercaseString];
    for (DKCityModel *obj in _cityModels) {
        if ([obj.name.uppercaseString containsString:searchText] || [obj.pinYin.uppercaseString containsString:searchText] || [obj.pinYinHead.uppercaseString containsString:searchText]) {
            [array addObject:obj];
        }
    }
    return array;
}

方式二 :使用謂詞

searchText  = searchText.uppercaseString;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@" pinYinHead.uppercaseString  contains %@ or  name.uppercaseString  contains %@  or pinYin.uppercaseString  contains %@ ",searchText,searchText,searchText];
 return [_cityModels filteredArrayUsingPredicate:predicate];

很明顯使用謂詞代碼量更少,代碼更簡單。

正則表達式進行判斷

利用NSPredicate 的evaluateWithObject 方法進行正則匹配。

#pragma 正則匹配手機號
+ (BOOL)checkTelNumber:(NSString *) telNumber {
    NSString *pattern = @^1+[3578]+\d{9};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:telNumber];
    return isMatch;
}
  
  
#pragma 正則匹配用戶密碼6-18位數(shù)字和字母組合
+ (BOOL)checkPassword:(NSString *) password {
    NSString *pattern = @^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9]{6,18};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:password];
    return isMatch;
      
}
  
#pragma 正則匹配用戶姓名,20位的中文或英文
+ (BOOL)checkUserName : (NSString *) userName {
    NSString *pattern = @^[a-zA-Z一-龥]{1,20};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:userName];
    return isMatch;  
}
  
  
#pragma 正則匹配用戶身份證號15或18位
+ (BOOL)checkUserIdCard: (NSString *) idCard{
    NSString *pattern = @(^[0-9]{15}$)|([0-9]{17}([0-9]|X)$);
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:idCard];
    return isMatch;
}
  
#pragma 正則匹員工號,12位的數(shù)字
+ (BOOL)checkEmployeeNumber : (NSString *) number{
    NSString *pattern = @^[0-9]{12}; 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:number];
    return isMatch;
      
}
  
#pragma 正則匹配URL
+ (BOOL)checkURL : (NSString *) url{
    NSString *pattern = @^[0-9A-Za-z]{1,50};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:url];
    return isMatch;
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容