溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

NSPredicate

發(fā)布時(shí)間:2020-10-01 05:05:35 來(lái)源:網(wǎng)絡(luò) 閱讀:187 作者:forest馮宋林 欄目:開(kāi)發(fā)技術(shù)

NSPredicate是什么

NSPredicate:謂詞
字面翻譯是這個(gè)意思,但是我覺(jué)得謂詞這個(gè)詞太難以理解了
NSPredicate的具體用途應(yīng)該還是過(guò)濾,類(lèi)似于過(guò)濾條件之類(lèi)的,相當(dāng)于一個(gè)主語(yǔ)的謂語(yǔ),所以說(shuō)會(huì)是謂詞這個(gè)名字。(我是這么理解的)

NSPredicate的創(chuàng)建

我們看到創(chuàng)建謂詞使用類(lèi)方法predicateWithFormat: (NSString*) format,format 里的東西真的
和SQL 的where 條件差不多。
另外,參數(shù)format 與NSLog 的格式化模版差不多,如果1 和
188.0 是傳遞過(guò)來(lái)的參數(shù),你可以寫(xiě)成如下的形式:
@"pid>%d and height<%f",1,188.0

NSPredicate中主要的幾種運(yùn)算方式

1.比較運(yùn)算符 > 、< 、== 、 >= 、<= 、 !=
例:@"number >= 99"

2.邏輯運(yùn)算符:AND、OR、NOT 這幾個(gè)運(yùn)算符計(jì)算并、或、非的結(jié)果。

3.范圍運(yùn)算符:IN 、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}"

4.字符串本身:SELF
例:@"SELF == 'APPLE'"

5.字符串相關(guān):BEGINSWITH、ENDSWITH、CONTAINS
例: @"name CONTAIN[cd] 'ang'" //包含某個(gè)字符串
@"name BEGINSWITH[c] 'sh'" //以某個(gè)字符串開(kāi)頭
@"name ENDSWITH[d] 'ang'" //以某個(gè)字符串結(jié)束
注:[c]不區(qū)分大小寫(xiě) , [d]不區(qū)分發(fā)音符號(hào)即沒(méi)有重音符號(hào) , [cd]既不區(qū)分大小寫(xiě),也不區(qū)分發(fā)音符號(hào)。

6.通配符:LIKE
例:@"name LIKE[cd] '*er*'" //*代表通配符,Like也接受[cd].
@"name LIKE[cd] '???er*'"

7.正則表達(dá)式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A開(kāi)頭,e結(jié)尾
@"name MATCHES %@",regex

如何使用NSPredicate對(duì)一個(gè)自定義實(shí)體進(jìn)行篩選

NSPredicate我暫時(shí)都是用于過(guò)濾的,否則我們過(guò)濾就需要自己寫(xiě)判斷 寫(xiě)循環(huán),去判斷輸出了。
接下來(lái)就上代碼和例子吧。

建立一個(gè)實(shí)體類(lèi) Dog

@property (copy   , nonatomic) NSString* name; 
@property (assign , nonatomic) int       age ;

這樣我們就有一個(gè)類(lèi)了
我們創(chuàng)建 5只Dog的實(shí)體

Dog * dog1=[Dog news];dog1.name=@"這是第一只Dog";dog1.age=@"11";
Dog * dog2=[Dog news];dog2.name=@"這是第二只Dog";dog2.age=@"22";
Dog * dog3=[Dog news];dog3.name=@"這是第三只Dog";dog3.age=@"33";
Dog * dog4=[Dog news];dog4.name=@"這是第四只Dog";dog4.age=@"44";
Dog * dog5=[Dog news];dog5.name=@"這是第五只Dog";dog5.age=@"55";

不要吐槽我的Dogs的年齡 → ?!?br />然后我們需要一個(gè)Array把他們都裝進(jìn)去

NSArray * dogArr=@[dog1,dog2,dog3,dog4,dog5];

醬紫所有的Dog都裝到一個(gè)數(shù)組里了

使用NSPredicate的篩選

  1. 沒(méi)有使用NSPredicate的篩選應(yīng)該大家都會(huì)寫(xiě),循環(huán)+判斷。。。

  2. 使用NSPredicate的篩選

具體使用的代碼
//創(chuàng)建謂詞的對(duì)象 謂詞條件是基于KVC的,所以需要說(shuō)明一點(diǎn),加入Dog里面有個(gè)屬性是Doginfo指向Doginfo類(lèi),在使用的時(shí)候 我們的條件就要寫(xiě)成Doginfo.xxx了。
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name=='這是第一只Dog' AND age ==11"];
for(Dog * d in dogArr)
{
    if([predicate evaluateWithObject:d])
    {
        NSLog(d.name);
    }
}

以上的代碼打印出來(lái)的結(jié)果就是 這是第一只Dog

NSPredicate篩選一個(gè)對(duì)象邏輯還是很清晰的,不過(guò)這里比較麻煩的就是 還有一個(gè)循環(huán),這里我們會(huì)發(fā)現(xiàn)數(shù)組提供了一個(gè)方法可以更方便的檢索數(shù)組對(duì)象

直接篩選出一個(gè)符合謂詞的新數(shù)組。

NSPredicate *pre = [NSPredicate predicateWithFormat:@"age >11"];
NSMutableArray *arrayPre=[dogArr filteredArrayUsingPredicate: pre];

arrayPre里面的對(duì)象就會(huì)是 除了dog1之外的所有的dog。(至于為什么看我的條件...)

看到這里發(fā)現(xiàn)NSPredicate 可以用于自定義的實(shí)體的檢索、篩選,那如果用于 NSString,NSInteger,bool呢?那我們?cè)倏匆欢未a吧
NSArray *arrays=[NSArray arrayWithObjects: @"Apple", @"Google", @"MircoSoft", nil];
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF=='Apple'"];

上面這段代碼是匹配字符串的時(shí)候 NSPredicate 需要如何聲明

使用NSPredicate在兩個(gè)數(shù)組之間進(jìn)行差異篩選

NSArray* array = @[@"aa",@"bb"];
NSArray* array2 = @[@"aa",@"bb",@"cc",@"dd"];
NSPredicate* thePredicate = [NSPredicate predicateWithFormat:@"NOT(SELF in %@)",array];
NSArray* arr3 = [array2 filteredArrayUsingPredicate:thePredicate];
NSLog(@"%@",arr3);

上面的代碼輸出結(jié)果 arr3={@"cc" ,@"dd"}
這樣大家就很容易理解了
SELF在前面有介紹過(guò) 可以往回翻閱一下

如何使用正則篩選一個(gè)數(shù)組

NSString *regex = @"^A.+e$";//以A 開(kāi)頭,以e 結(jié)尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Apple"]){
    printf("YES\n");
}else{
    printf("NO\n");
}

關(guān)于NSPredicate的其他說(shuō)明和注意事項(xiàng),以及技巧

  1. 動(dòng)態(tài)屬性名

假如你的代碼如下

NSPredicate *p = [NSPredicate predicateWithFormat:@"name = %@", @"name1"];

顯然代碼沒(méi)有任何問(wèn)題,但是這個(gè)不是最好的寫(xiě)法我建議如下寫(xiě)法:

NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@"name1", @"NAME",nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];

這樣看上去可能會(huì)讓代碼邏輯更清晰。

當(dāng)過(guò)濾條件字段都是動(dòng)態(tài)的時(shí)候

NSString *key = @"name";     
NSString *value = @"name1";      
NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ = %@", key, value];

然后當(dāng)你執(zhí)行到第三行的時(shí)候代碼就會(huì)報(bào)錯(cuò)!
邏輯上沒(méi)錯(cuò)誤?。。?!為什么會(huì)出錯(cuò)呢?
NSPredicate要自動(dòng)添加引號(hào),所以最后得到的格式應(yīng)該是@"'name' = 'name1'"。明顯不對(duì)。要做的就是:

NSPredicate *p = [NSPredicate predicateWithFormat:@"%K = %@", key, value];

總結(jié)

NSPredicate 的簡(jiǎn)單的使用就介紹到這里,這里有些都是從網(wǎng)絡(luò)上其他人的額博客轉(zhuǎn)過(guò)來(lái)的內(nèi)容,我自己加以修改和一些自己的理解。希望可以幫到大家。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI