這篇文章給大家分享的是有關(guān)iOS中謂詞NSPredicate怎么用的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計、成都做網(wǎng)站、湘潭縣網(wǎng)絡(luò)推廣、小程序設(shè)計、湘潭縣網(wǎng)絡(luò)營銷、湘潭縣企業(yè)策劃、湘潭縣品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供湘潭縣建站搭建服務(wù),24小時服務(wù)熱線:18982081108,官方網(wǎng)址:aaarwkj.com
前言
首先,我們需要知道何謂謂詞,讓我們看看官方的解釋:
The NSPredicate class is used to define logical conditions used to constrain a search either for a fetch or for in-memory filtering.
NSPredicate類是用來定義邏輯條件約束的獲取或內(nèi)存中的過濾搜索。
可以使用謂詞來表示邏輯條件,用于描述對象持久性存儲在內(nèi)存中的對象過濾。其實意思就是:我是一個過濾器,不符合條件的都滾開。
一、NSPredicate的基本語法
我們使用一門語言,無論是外語還是計算機語言,總是從語法開始的,這樣我們才能正確的把握邏輯。所以我們從語法開始說起。在這部分我們僅關(guān)心其語法的使用
只要我們使用謂詞(NSPredicate)都需要為謂詞定義謂詞表達式,而這個表達式必須是一個返回BOOL的值。
謂詞表達式由表達式、運算符和值構(gòu)成。
1.比較運算符
比較運算符如下
=、==:判斷兩個表達式是否相等,在謂詞中=和==是相同的意思都是判斷,而沒有賦值這一說
NSNumber *testNumber = @123; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"]; if ([predicate evaluateWithObject:testNumber]) { NSLog(@"testString:%@", testNumber); }
我們可以看到輸出的內(nèi)容為:
2016-01-07 11:12:27.281 PredicteDemo[4130:80412] testString:123
>=,=>:判斷左邊表達式的值是否大于或等于右邊表達式的值
<=,=<:判斷左邊表達式的值是否小于或等于右邊表達式的值
>:判斷左邊表達式的值是否大于右邊表達式的值
<:判斷左邊表達式的值是否小于右邊表達式的值
!=、<>:判斷兩個表達式是否不相等
BETWEEN:BETWEEN表達式必須滿足表達式 BETWEEN {下限,上限}的格式,要求該表達式必須大于或等于下限,并小于或等于上限
NSNumber *testNumber = @123; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"]; if ([predicate evaluateWithObject:testNumber]) { NSLog(@"testString:%@", testNumber); } else { NSLog(@"不符合條件"); }
輸出結(jié)果為:
2016-01-07 11:20:39.921 PredicteDemo[4366:85408] testString:123
2.邏輯運算符
AND、&&:邏輯與,要求兩個表達式的值都為YES時,結(jié)果才為YES。
NSArray *testArray = @[@1, @2, @3, @4, @5, @6]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"]; NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate]; NSLog(@"filterArray:%@", filterArray);
輸出結(jié)果為:
2016-01-07 11:27:01.885 PredicteDemo[4531:89537] filterArray:(
3,
4
)
OR、||:邏輯或,要求其中一個表達式為YES時,結(jié)果就是YES
NOT、 !:邏輯非,對原有的表達式取反
3.字符串比較運算符
BEGINSWITH:檢查某個字符串是否以指定的字符串開頭(如判斷字符串是否以a開頭:BEGINSWITH 'a')
ENDSWITH:檢查某個字符串是否以指定的字符串結(jié)尾
CONTAINS:檢查某個字符串是否包含指定的字符串
LIKE:檢查某個字符串是否匹配指定的字符串模板。其之后可以跟?代表一個字符和*代表任意多個字符兩個通配符。比如"name LIKE '*ac*'",這表示name的值中包含ac則返回YES;"name LIKE '?ac*'",表示name的第2、3個字符為ac時返回YES。
MATCHES:檢查某個字符串是否匹配指定的正則表達式。雖然正則表達式的執(zhí)行效率是最低的,但其功能是最強大的,也是我們最常用的。
注:字符串比較都是區(qū)分大小寫和重音符號的。如:café和cafe是不一樣的,Cafe和cafe也是不一樣的。如果希望字符串比較運算不區(qū)分大小寫和重音符號,請在這些運算符后使用[c],[d]選項。其中[c]是不區(qū)分大小寫,[d]是不區(qū)分重音符號,其寫在字符串比較運算符之后,比如:name LIKE[cd] 'cafe',那么不論name是cafe、Cafe還是café上面的表達式都會返回YES。
4.集合運算符
ANY、SOME:集合中任意一個元素滿足條件,就返回YES。
ALL:集合中所有元素都滿足條件,才返回YES。
NONE:集合中沒有任何元素滿足條件就返回YES。如:NONE person.age < 18,表示person集合中所有元素的age>=18時,才返回YES。
IN:等價于SQL語句中的IN運算符,只有當(dāng)左邊表達式或值出現(xiàn)在右邊的集合中才會返回YES。我們通過一個例子來看一下
NSArray *filterArray = @[@"ab", @"abc"]; NSArray *array = @[@"a", @"ab", @"abc", @"abcd"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray]; NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);
代碼的作用是將array中和filterArray中相同的元素去除,輸出為:
2016-01-07 13:17:43.669 PredicteDemo[6701:136206] (
a,
abcd
)
array[index]:返回array數(shù)組中index索引處的元素
array[FIRST]:返回array數(shù)組中第一個元素
array[LAST]:返回array數(shù)組中最后一個元素
array[SIZE]:返回array數(shù)組中元素的個數(shù)
5.直接量
在謂詞表達式中可以使用如下直接量
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ù)字
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
注:雖然大小寫都可以,但是更推薦使用大寫來表示這些保留字
二、謂詞的用法
1.定義謂詞
一般我們使用下列方法來定義一個謂詞
NSPredicate *predicate = [NSPredicate predicateWithFormat:<#(nonnull NSString *), ...#>];
下面我們通過幾個簡單的例子來看看它該如何使用:
首先我們需要定義一個模型,因為示例中需要用到它
ZLPersonModel.h
#import <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, ZLPersonSex) { ZLPersonSexMale = 0, ZLPersonSexFamale }; @interface ZLPersonModel : NSObject /** NSString 姓名 */ @property (nonatomic, copy) NSString *name; /** NSUInteger 年齡 */ @property (nonatomic, assign, readonly) NSUInteger age; /** ZLPersonSex 性別 */ @property (nonatomic, assign, readonly) ZLPersonSex sex; + (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex; @end
ZLPersonModel.m
#import "ZLPersonModel.h" @implementation ZLPersonModel - (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex { if (self = [super init]) { _name = name; _age = age; _sex = sex; } return self; } + (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex { return [[self alloc] initWithName:name age:age sex:sex]; } - (NSString *)description { return [NSString stringWithFormat:@"[name = %@, age = %ld, sex = %ld]", self.name, self.age, self.sex]; } @end
下面讓我們進入正題
例一:(最簡單的使用)
ZLPersonModel *sunnyzl = [ZLPersonModel personWithName:@"sunnyzl" age:29 sex:ZLPersonSexMale]; ZLPersonModel *jack = [ZLPersonModel personWithName:@"jack" age:22 sex:ZLPersonSexMale]; // 首先我們來看一些簡單的使用 // 1.判斷姓名是否是以s開頭的 NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"name LIKE 's*'"]; // 輸出為:sunnyzl:1, jack:0 NSLog(@"sunnyzl:%d, jack:%d", [pred1 evaluateWithObject:sunnyzl], [pred1 evaluateWithObject:jack]); // 2.判斷年齡是否大于25 NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"age > 25"]; // 輸出為:sunnyzl的年齡是否大于25:1, jack的年齡是否大于25:0 NSLog(@"sunnyzl的年齡是否大于25:%d, jack的年齡是否大于25:%d", [pred2 evaluateWithObject:sunnyzl], [pred2 evaluateWithObject:jack]);
看到這里我們會發(fā)現(xiàn)evaluateWithObject:方法返回的是一個BOOL值,如果符合條件就返回YES,不符合就返回NO。而即使是最簡單的使用也有一些大用處,比如以前我們寫判斷手機號碼、郵編等等,像我就喜歡用John Engelhart大神的RegexKitLite,然而由于年代久遠需要導(dǎo)入libicucore.dylib庫(xcode7為libicucore.tbd)且由于是mrc又需要添加-fno-objc-arc,至此我們才能使用。然而使用謂詞讓我們可以用同樣簡潔的代碼實現(xiàn)相同的功能
例二:
(判斷手機號是否正確)
- (BOOL)checkPhoneNumber:(NSString *)phoneNumber { NSString *regex = @"^[1][3-8]\\d{9}$"; NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [pred evaluateWithObject:phoneNumber]; }
例三:檢測字符串中是否有特殊字符
- (BOOL)checkSpecialCharacter:(NSString *)string { NSString *regex = @"[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]+"; NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [pred evaluateWithObject:string]; }
2.使用謂詞過濾集合
此部分是我們需要掌握的重點,因為從這里我們就可以看到謂詞的真正的強大之處
其實謂詞本身就代表了一個邏輯條件,計算謂詞之后返回的結(jié)果永遠為BOOL類型的值。而謂詞最常用的功能就是對集合進行過濾。當(dāng)程序使用謂詞對集合元素進行過濾時,程序會自動遍歷其元素,并根據(jù)集合元素來計算謂詞的值,當(dāng)這個集合中的元素計算謂詞并返回YES時,這個元素才會被保留下來。請注意程序會自動遍歷其元素,它會將自動遍歷過之后返回為YES的值重新組合成一個集合返回。
其實類似于我們使用tableView設(shè)置索引時使用的下段代碼
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [self.cityGroup valueForKey:@"title"]; }
中的[self.cityGroup valueForKey:@"title"]。它的作用是遍歷所有title并將得到的值組成新的數(shù)組。
NSArray提供了如下方法使用謂詞來過濾集合
- (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate
:使用指定的謂詞過濾NSArray集合,返回符合條件的元素組成的新集合
NSMutableArray提供了如下方法使用謂詞來過濾集合
- (void)filterUsingPredicate:(NSPredicate *)predicate
:使用指定的謂詞過濾NSMutableArray,剔除集合中不符合條件的元素
NSSet提供了如下方法使用謂詞來過濾集合
- (NSSet<ObjectType> *)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0)
:作用同NSArray中的方法
NSMutableSet提供了如下方法使用謂詞來過濾集合
- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0)
:作用同NSMutableArray中的方法。
通過上面的描述可以看出,使用謂詞過濾不可變集合和可變集合的區(qū)別是:過濾不可變集合時,會返回符合條件的集合元素組成的新集合;過濾可變集合時,沒有返回值,會直接剔除不符合條件的集合元素
下面讓我們來看幾個例子:
例一:
NSMutableArray *arrayM = [@[@20, @40, @50, @30, @60, @70] mutableCopy]; // 過濾大于50的值 NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF > 50"]; [arrayM filterUsingPredicate:pred1]; NSLog(@"arrayM:%@", arrayM); NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale], [ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale], [ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale], [ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]]; // 要求取出包含‘son'的元素 NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'son'"]; NSArray *newArray = [array filteredArrayUsingPredicate:pred2]; NSLog(@"%@", newArray);
輸出為
2016-01-07 16:50:09.510 PredicteDemo[13660:293822] arrayM:(
60,
70
)
2016-01-07 16:50:09.511 PredicteDemo[13660:293822] (
"[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
)
從這個例子我們就可以看到NSPredicate有多么強大,如果讓我們用其他的方法來實現(xiàn)又是一大堆if...else。
讓我們來回顧一下上面的從第二個數(shù)組中去除第一個數(shù)組中相同的元素
例二:
NSArray *filterArray = @[@"ab", @"abc"]; NSArray *array = @[@"a", @"ab", @"abc", @"abcd"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray]; NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);
輸出為:
2016-01-07 13:17:43.669 PredicteDemo[6701:136206] (
a,
abcd
)
如果我們不用NSPredicate的話,肯定又是各種if...else,for循環(huán)等等??梢钥闯鯪SPredicate的出現(xiàn)為我們節(jié)省了大量的時間和精力。
3.在謂詞中使用占位符參數(shù)
我們上面所有的例子中謂詞總是固定的,然而我們在現(xiàn)實中處理變量時決定了謂詞應(yīng)該是可變的。下面我們來看看如果讓謂詞變化起來。
首先如果我們想在謂詞表達式中使用變量,那么我們需要了解下列兩種占位符
%K:用于動態(tài)傳入屬性名
%@:用于動態(tài)設(shè)置屬性值
其實相當(dāng)于變量名與變量值
除此之外,還可以在謂詞表達式中使用動態(tài)改變的屬性值,就像環(huán)境變量一樣
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS $VALUE"];
上述表達式中,開頭,隨著程序改變$VALUE這個謂詞表達式的比較條件就可以動態(tài)改變。
下面我們通過一個例子來看看這三個重要的占位符應(yīng)該如何使用
例一:
NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale], [ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale], [ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale], [ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]]; // 定義一個property來存放屬性名,定義一個value來存放值 NSString *property = @"name"; NSString *value = @"Jack"; // 該謂詞的作用是如果元素中property屬性含有值value時就取出放入新的數(shù)組內(nèi),這里是name包含Jack NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value]; NSArray *newArray = [array filteredArrayUsingPredicate:pred]; NSLog(@"newArray:%@", newArray); // 創(chuàng)建謂詞,屬性名改為age,要求這個age包含$VALUE字符串 NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"]; // 指定$VALUE的值為 25 NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}]; NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1]; NSLog(@"newArray1:%@", newArray1); // 修改 $VALUE的值為32 NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}]; NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2]; NSLog(@"newArray2:%@", newArray2);
輸出為
2016-01-07 17:28:02.062 PredicteDemo[14542:309494] newArray:(
"[name = Jack, age = 20, sex = 0]",
"[name = Jackson, age = 30, sex = 0]"
)
2016-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray1:(
"[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
)
2016-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray2:(
"[name = Johnson, age = 35, sex = 0]"
)
從上例中我們主要可以看出來%K和$VALUE的含義。
感謝各位的閱讀!關(guān)于“iOS中謂詞NSPredicate怎么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
網(wǎng)站標(biāo)題:iOS中謂詞NSPredicate怎么用
地址分享:http://aaarwkj.com/article10/jessgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、虛擬主機、自適應(yīng)網(wǎng)站、搜索引擎優(yōu)化、建站公司、用戶體驗
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)