亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS中謂詞(NSPredicate)的基本入門使用教程

2020-07-26 02:21:50
字體:
來源:轉載
供稿:網友

前言

首先,我們需要知道何謂謂詞,讓我們看看官方的解釋:

The NSPredicate class is used to define logical conditions used to constrain a search either for a fetch or for in-memory filtering.

NSPredicate類是用來定義邏輯條件約束的獲取或內存中的過濾搜索。
可以使用謂詞來表示邏輯條件,用于描述對象持久性存儲在內存中的對象過濾。其實意思就是:我是一個過濾器,不符合條件的都滾開。

一、NSPredicate的基本語法

我們使用一門語言,無論是外語還是計算機語言,總是從語法開始的,這樣我們才能正確的把握邏輯。所以我們從語法開始說起。在這部分我們僅關心其語法的使用

只要我們使用謂詞(NSPredicate)都需要為謂詞定義謂詞表達式,而這個表達式必須是一個返回BOOL的值。
謂詞表達式由表達式、運算符和值構成。

1.比較運算符

比較運算符如下

=、==:判斷兩個表達式是否相等,在謂詞中=和==是相同的意思都是判斷,而沒有賦值這一說

NSNumber *testNumber = @123; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"]; if ([predicate evaluateWithObject:testNumber]) { NSLog(@"testString:%@", testNumber); }

我們可以看到輸出的內容為:

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(@"不符合條件"); }

輸出結果為:

2016-01-07 11:20:39.921 PredicteDemo[4366:85408] testString:123

2.邏輯運算符

AND、&&:邏輯與,要求兩個表達式的值都為YES時,結果才為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);

輸出結果為:

2016-01-07 11:27:01.885 PredicteDemo[4531:89537] filterArray:(
    3,
    4
)

  • OR、||:邏輯或,要求其中一個表達式為YES時,結果就是YES
  • NOT、 !:邏輯非,對原有的表達式取反

3.字符串比較運算符

  • BEGINSWITH:檢查某個字符串是否以指定的字符串開頭(如判斷字符串是否以a開頭:BEGINSWITH 'a')
  • ENDSWITH:檢查某個字符串是否以指定的字符串結尾
  • CONTAINS:檢查某個字符串是否包含指定的字符串
  • LIKE:檢查某個字符串是否匹配指定的字符串模板。其之后可以跟?代表一個字符和*代表任意多個字符兩個通配符。比如"name LIKE '*ac*'",這表示name的值中包含ac則返回YES;"name LIKE '?ac*'",表示name的第2、3個字符為ac時返回YES。
  • MATCHES:檢查某個字符串是否匹配指定的正則表達式。雖然正則表達式的執行效率是最低的,但其功能是最強大的,也是我們最常用的。

注:字符串比較都是區分大小寫和重音符號的。如:café和cafe是不一樣的,Cafe和cafe也是不一樣的。如果希望字符串比較運算不區分大小寫和重音符號,請在這些運算符后使用[c],[d]選項。其中[c]是不區分大小寫,[d]是不區分重音符號,其寫在字符串比較運算符之后,比如: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運算符,只有當左邊表達式或值出現在右邊的集合中才會返回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數組中index索引處的元素
  • array[FIRST]:返回array數組中第一個元素
  • array[LAST]:返回array數組中最后一個元素
  • array[SIZE]:返回array數組中元素的個數

5.直接量

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

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

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]);

看到這里我們會發現evaluateWithObject:方法返回的是一個BOOL值,如果符合條件就返回YES,不符合就返回NO。而即使是最簡單的使用也有一些大用處,比如以前我們寫判斷手機號碼、郵編等等,像我就喜歡用John Engelhart大神的RegexKitLite,然而由于年代久遠需要導入libicucore.dylib庫(xcode7為libicucore.tbd)且由于是mrc又需要添加-fno-objc-arc,至此我們才能使用。然而使用謂詞讓我們可以用同樣簡潔的代碼實現相同的功能

例二:

(判斷手機號是否正確)

 - (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.使用謂詞過濾集合

此部分是我們需要掌握的重點,因為從這里我們就可以看到謂詞的真正的強大之處

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

其實類似于我們使用tableView設置索引時使用的下段代碼

- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{ return [self.cityGroup valueForKey:@"title"];}

中的[self.cityGroup valueForKey:@"title"]。它的作用是遍歷所有title并將得到的值組成新的數組。

  • 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中的方法。
    通過上面的描述可以看出,使用謂詞過濾不可變集合和可變集合的區別是:過濾不可變集合時,會返回符合條件的集合元素組成的新集合;過濾可變集合時,沒有返回值,會直接剔除不符合條件的集合元素

下面讓我們來看幾個例子:

例一:

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有多么強大,如果讓我們用其他的方法來實現又是一大堆if...else。
讓我們來回顧一下上面的從第二個數組中去除第一個數組中相同的元素

例二:

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循環等等??梢钥闯鯪SPredicate的出現為我們節省了大量的時間和精力。

3.在謂詞中使用占位符參數

我們上面所有的例子中謂詞總是固定的,然而我們在現實中處理變量時決定了謂詞應該是可變的。下面我們來看看如果讓謂詞變化起來。

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

  • %K:用于動態傳入屬性名
  • %@:用于動態設置屬性值

其實相當于變量名與變量值

除此之外,還可以在謂詞表達式中使用動態改變的屬性值,就像環境變量一樣

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

上述表達式中,開頭,隨著程序改變$VALUE這個謂詞表達式的比較條件就可以動態改變。

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

例一:

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時就取出放入新的數組內,這里是name包含Jack NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value]; NSArray *newArray = [array filteredArrayUsingPredicate:pred]; NSLog(@"newArray:%@", newArray);  // 創建謂詞,屬性名改為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的含義。

那么至此NSPredicate就到到此介紹完畢。

因為本人水平有限,如果有什么好的建議請聯系我。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久亚洲精品| 国产精品久久久久久久久久东京| 欧美激情二区三区| 青青草成人在线| 欧美精品第一页在线播放| 欧美日韩国产综合视频在线观看中文| 57pao国产精品一区| 欧美精品久久久久久久久久| 一本色道久久综合狠狠躁篇的优点| 九九久久综合网站| 久久最新资源网| 久久在线精品视频| xxx一区二区| 日韩精品中文在线观看| 欧美福利在线观看| 亚洲国产成人精品电影| 国产欧美婷婷中文| 国产精品久久一| 亚洲成人三级在线| 国产精品r级在线| 九九视频这里只有精品| 超碰97人人做人人爱少妇| www.久久草.com| 黑人与娇小精品av专区| 中文字幕日韩精品有码视频| 日本电影亚洲天堂| 欧美黑人极品猛少妇色xxxxx| 亚洲自拍在线观看| 国产美女精品视频免费观看| 亚洲欧美国产日韩天堂区| 国产精品免费一区二区三区都可以| 色狠狠av一区二区三区香蕉蜜桃| 亚洲国产欧美在线成人app| 亚洲成人在线网| 欧美激情亚洲另类| 91色在线视频| 26uuu久久噜噜噜噜| 国产精品久久久久久搜索| 97免费视频在线播放| 国产精品高潮粉嫩av| 97在线视频免费观看| 欧美亚洲国产日韩2020| 成人乱色短篇合集| 久久影视电视剧免费网站清宫辞电视| 久久精品久久久久久| 欧美日韩裸体免费视频| 欧美激情精品久久久久久变态| 乱亲女秽乱长久久久| 欧美一区第一页| 久久久久久亚洲精品中文字幕| 日韩美女av在线免费观看| 欧洲日韩成人av| 日韩精品在线视频美女| 亚洲а∨天堂久久精品喷水| 91九色国产社区在线观看| 国产91色在线免费| 亚洲人成电影在线播放| 欧洲精品在线视频| 91精品视频播放| 国产精品吊钟奶在线| 欧美国产精品日韩| 亚洲欧美成人精品| 91精品视频大全| 亚洲午夜未删减在线观看| 欧美日韩国产专区| 欧美精品国产精品日韩精品| 欧美日韩国产91| 亚洲第一网中文字幕| 久久精品视频在线| 日韩欧美国产中文字幕| 国产精品视频99| 日韩在线视频中文字幕| 自拍偷拍免费精品| 久久成年人视频| 欧美日韩亚洲视频| 黄色精品一区二区| 欧美日韩成人黄色| 精品亚洲一区二区三区在线播放| 国产做受高潮69| 91精品国产自产在线老师啪| 欧美另类老肥妇| 九九九热精品免费视频观看网站| 日韩高清电影免费观看完整版| 亚洲精品白浆高清久久久久久| 91精品国产高清自在线| 992tv在线成人免费观看| 亚洲免费视频观看| 992tv在线成人免费观看| 成人午夜一级二级三级| 国产精品在线看| 伊人久久久久久久久久| 九九精品视频在线| 欧美极品少妇xxxxⅹ裸体艺术| 中文字幕亚洲一区二区三区| 成人激情视频网| 亚洲男人的天堂网站| 国产精品激情自拍| 久久久亚洲天堂| 日本高清久久天堂| 一本色道久久88亚洲综合88| 欧美电影在线播放| 8x海外华人永久免费日韩内陆视频| 国产在线精品一区免费香蕉| 亚洲福利在线视频| 国产精品草莓在线免费观看| 欧美日本高清一区| 久久全国免费视频| 久久天堂av综合合色| 国内精品久久久| 欧洲亚洲妇女av| 亚洲一区二区久久久久久| 欧美三级欧美成人高清www| 亚洲国产精久久久久久| 最新的欧美黄色| 精品美女久久久久久免费| 色与欲影视天天看综合网| 高清欧美性猛交xxxx| 国产精品入口尤物| 久久久久久久色| 久久综合九色九九| 国产69久久精品成人看| 日本亚洲欧美三级| 亚洲色图五月天| 国产精品精品视频一区二区三区| 国产亚洲美女久久| 久久久亚洲精品视频| 在线观看国产精品淫| 91沈先生作品| 国产精品第1页| 亚洲天堂第一页| 国产www精品| 国产精品xxx视频| 成人午夜黄色影院| 欧美日韩精品二区| 精品一区电影国产| 国产一区二区三区直播精品电影| 欧美日韩一区二区在线| 亚洲丁香久久久| 日韩av一区二区在线观看| 欧美电影免费观看| 亚洲跨种族黑人xxx| 国产精品高潮视频| 国产成人在线一区二区| 亚洲精品久久7777777| 日韩精品在线第一页| 国产精品中文久久久久久久| 欧美一区二区三区……| 精品国产一区二区三区久久狼黑人| 成人久久一区二区三区| 97精品国产91久久久久久| 丁香五六月婷婷久久激情| 亚洲国产精品女人久久久| 欧美一级片久久久久久久| 日本成人精品在线| 成人在线小视频| 动漫精品一区二区| 欧美午夜激情小视频| 蜜臀久久99精品久久久无需会员| xxxx欧美18另类的高清| 亚洲大尺度美女在线| 裸体女人亚洲精品一区| 国产日韩在线看片| 97久久久免费福利网址| 国产精品免费一区二区三区都可以|