NSPredicate 這個類主要有兩個方面的作用:
- 從集合類中過濾數(shù)據(jù)
- 和正則表達式進行正則判斷(比方說驗證手機號,郵箱,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];
}];
- 過濾對象的firstName屬性 firstName = 'Bob',執(zhí)行結(jié)果是獲取 firstName = 'Bob' 的數(shù)組
NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];
NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);
["Bob Jones"]
- 過濾對象 age >= 30
NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];
NSLog(@"30's: %@", [people filteredArrayUsingPredicate:thirtiesPredicate]);
["Charlie Smith", "Quentin Alberts"]
- 過濾年齡 在 26和30之間的情況
NSPredicate *agePredicate2 = [NSPredicate predicateWithFormat:@"age BETWEEN {26, 30}"];
NSLog(@"age2:%@",[people filteredArrayUsingPredicate:agePredicate2]);
- 過濾年齡在 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 },或者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;
}