iOS(NSPredicate) 謂詞的使用

參考
iOS-謂詞的使用詳解
NSPredicate 謂詞


NSPredicate

A definition of logical conditions used to constrain a search either for a fetch or for in-memory filtering.
一種邏輯條件的定義,可以根據(jù)定義的模糊查詢條件,對內(nèi)存對象進(jìn)行過濾搜索。


1.比較運(yùn)算符

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSNumber *number = @123;
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];
        NSLog(@"%@", [predicate evaluateWithObject:number] ? @"YES" : @"NO");
    }
    return 0;
}

// RESULT : YES

=、==:判斷兩個表達(dá)式是否相等
<=:判斷右邊表達(dá)式的值是否小于或等于右邊表達(dá)式的值
>=:判斷左邊表達(dá)式的值是否大于右邊表達(dá)式的值
<:判斷左邊表達(dá)式的值是否小于右邊表達(dá)式的值
> :判斷左邊表達(dá)式的值是否大于右邊表達(dá)式的值
!=:判斷兩個表達(dá)式是否不相等

BETWEEN {下限,上限}:必須大于或等于下限,并小于或等于上限

        NSNumber *number = @123;
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 123} "];
        NSLog(@"%@", [predicate evaluateWithObject:number] ? @"YES" : @"NO");

// RESULT : YES


2.邏輯運(yùn)算符

        NSArray *array = @[@1, @2, @3, @4, @5];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];
        NSArray *filterArray = [array filteredArrayUsingPredicate:predicate];
        NSLog(@"%@", filterArray);

// RESULT : (
    3,
    4
)

AND、&&:邏輯與,要求兩個表達(dá)式的值都為YES時,結(jié)果才為YES
OR、||:邏輯或,要求其中一個表達(dá)式為YES時,結(jié)果就是YES
NOT、 !:邏輯非,對原有的表達(dá)式取反


3.字符串比較運(yùn)算符

        NSString *string = @"abcd";
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@" %@ BEGINSWITH 'a'", string];
        NSLog(@"%@", [predicate evaluateWithObject:string] ? @"YES" : @"NO");

// RESULT : YES

ENDSWITH :檢查某個字符串是否以指定的字符串結(jié)尾
CONTAINS :檢查某個字符串是否包含指定的字符串

LIKE :檢查某個字符串是否匹配指定的字符串模板。其之后可以跟?代表一個字符和*代表任意多個字符兩個通配符。比如"name LIKE '*ac*'",這表示name的值中包含ac則返回YES;"name LIKE '?ac*'",表示name的第2、3個字符為ac時返回YES。

MATCHES:檢查某個字符串是否匹配指定的正則表達(dá)式。雖然正則表達(dá)式的執(zhí)行效率并不高,但其功能是最強(qiáng)大的,也是我們最常用的。

注: 字符串比較都是區(qū)分大小寫和重音符號的。如:café和cafe是不一樣的,Cafe和cafe也是不一樣的。如果希望字符串比較運(yùn)算不區(qū)分大小寫和重音符號,請在這些運(yùn)算符后使用[c],[d]選項。其中[c]是不區(qū)分大小寫,[d]是不區(qū)分重音符號,其寫在字符串比較運(yùn)算符之后,比如:"name LIKE[cd] 'cafe'",那么不論name是cafe、Cafe還是café上面的表達(dá)式都會返回YES。


4.集合運(yùn)算符

ANY、SOME :集合中任意一個元素滿足條件,就返回YES。

ALL :集合中所有元素都滿足條件,才返回YES。

NONE :集合中沒有任何元素滿足條件就返回YES。如:NONE person.age<18,表示person集合中所有元素的age>=18時,才返回YES。

IN:等價于SQL語句中的IN運(yùn)算符,只有當(dāng)左邊表達(dá)式或值出現(xiàn)在右邊的集合中才會返回YES。

        NSArray *array1 = @[@"a", @"ab", @"abc" ,@"abcd"];
        NSArray *array2 = @[@"ab", @"abc" ];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", array1];
        NSLog(@"%@", [array2 filteredArrayUsingPredicate:predicate]);

// RESULT : (
    ab,
    abc
)


5.直接量

在謂詞表達(dá)式中可以使用如下直接量 :

FALSE、NO:代表邏輯假
TRUE、YES:代表邏輯真
NULL、NIL:代表空值

SELF :代表正在被判斷的對象自身

"string"或'string':代表字符串
數(shù)組:和c中的寫法相同,如:{'one', 'two', 'three'}。
數(shù)值:包括整數(shù)、小數(shù)和科學(xué)計數(shù)法表示的形式
十六進(jìn)制數(shù):0x開頭的數(shù)字
八進(jìn)制:0o開頭的數(shù)字
二進(jìn)制:0b開頭的數(shù)字


實(shí)例

簡單的使用

//  1.判斷姓名是否是以s開頭的,上面已經(jīng)用過BEGINSWITH方法,這里用LIKE
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"name LIKE 's*'"];
NSLog(@"sunnyzl:%d, jack:%d", [pred1 evaluateWithObject:sunnyzl], [pred1 evaluateWithObject:jack]);
//  輸出為:sunnyzl:1, jack:0

//  2.判斷年齡是否大于25
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"age > 25"];
NSLog(@"sunnyzl的年齡是否大于25:%d, jack的年齡是否大于25:%d", [pred2 evaluateWithObject:sunnyzl], [pred2 evaluateWithObject:jack]);
//  輸出為:sunnyzl的年齡是否大于25:1, jack的年齡是否大于25:0


搭配正則表達(dá)式使用

        NSString *regex = @"^[1][3-8]\\d{9}$";
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
        NSLog(@"%d", [predicate evaluateWithObject:@"13888888888"]);

// RESULT : 1


使用謂詞過濾集合

此部分是我們需要掌握的重點(diǎn),因?yàn)閺倪@里我們就可以看到謂詞的真正的強(qiáng)大之處

其實(shí)謂詞本身就代表了一個邏輯條件,計算謂詞之后返回的結(jié)果永遠(yuǎn)為BOOL類型的值。而謂詞最常用的功能就是對集合進(jìn)行過濾。當(dāng)程序使用謂詞對集合元素進(jìn)行過濾時,程序會自動遍歷其元素,并根據(jù)集合元素來計算謂詞的值,當(dāng)這個集合中的元素計算謂詞并返回YES時,這個元素才會被保留下來。請注意程序會自動遍歷其元素,它會將自動遍歷過之后返回為YES的值重新組合成一個集合返回。

  • NSArray提供了如下方法使用謂詞來過濾集合
    -- (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate;
    使用指定的謂詞過濾NSArray集合,返回符合條件的元素組成的新集合
        NSArray *array = @[@"aaajson", @"bbbjson", @"cccson", @"ddddd"];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'json'"];
        NSArray *newArray = [array filteredArrayUsingPredicate:predicate];
        NSLog(@"%@",newArray);

// RESULT:(
    aaajson,
    bbbjson
)

  • NSMutableArray提供了如下方法使用謂詞來過濾集合
    - (void)filterUsingPredicate:(NSPredicate *)predicate;
    使用指定的謂詞過濾NSMutableArray,剔除集合中不符合條件的元素
        NSMutableArray *arrayM = [@[@10, @20, @30, @40, @50, @60, @70] mutableCopy];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 50"];
        [arrayM filterUsingPredicate:predicate];
        NSLog(@"%@", arrayM);

// RESULT:(
    60,
    70
)

  • NSSet提供了如下方法使用謂詞來過濾集合

    - (NSSet<ObjectType> *)filteredSetUsingPredicate:(NSPredicate *)predicate作用同NSArray中的方法

  • NSMutableSet提供了如下方法使用謂詞來過濾集合

    - (void)filterUsingPredicate:(NSPredicate *)predicate作用同NSMutableArray中的方法。

通過上面的描述可以看出,使用謂詞過濾不可變集合和可變集合的區(qū)別是:過濾不可變集合時,會返回符合條件的集合元素組成的新集合;過濾可變集合時,沒有返回值,會直接剔除不符合條件的集合元素


在謂詞中使用占位符參數(shù)

首先如果我們想在謂詞表達(dá)式中使用變量,那么我們需要了解下列兩種占位符:

%K:用于動態(tài)傳入屬性名

%@:用于動態(tài)設(shè)置屬性值

其實(shí)相當(dāng)于變量名與變量值,除此之外,還可以在謂詞表達(dá)式中使用動態(tài)改變的屬性值,就像環(huán)境變量一樣

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS $VALUE"];

上述表達(dá)式中,$VALUE是一個可以動態(tài)變化的值,它其實(shí)最后是在字典中的一個key,所以可以根據(jù)你的需要寫不同的值,但是必須有 開頭,隨著程序改變`VALUE`這個謂詞表達(dá)式的比較條件就可以動態(tài)改變。

下面我們通過一個例子來看看這三個重要的占位符應(yīng)該如何使用

NSArray *array = @[[PersonModel personWithName:@"Jack" age:20],
[PersonModel personWithName:@"Rose" age:22],
[PersonModel personWithName:@"Jackson" age:30],
[PersonModel personWithName:@"Johnson" age:35];
//  定義一個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);

// RESULT:newArray:(
"[name = Jack, age = 20, sex = 0]",
"[name = Jackson, age = 30, sex = 0]"
)

//  創(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);

// RESULT:newArray1:(
"[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
)

//  修改 $VALUE的值為32
NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}];
NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];
NSLog(@"newArray2:%@", newArray2);

// RESULT: newArray2:(
"[name = Johnson, age = 35, sex = 0]"
)


謝謝你長的這么好看,還關(guān)注我!??!點(diǎn)個贊唄!!
如果有什么不對的請各位大佬留言提示,然后有什么別的需要改進(jìn)的提示請聯(lián)系我我會及時補(bǔ)充~

over.over.

部分文章來自轉(zhuǎn)載他人,如有侵權(quán)請聯(lián)系作者刪除

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

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

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