最近在看一個(gè)開(kāi)源項(xiàng)目,里面用到了NSPredicate類(lèi),感覺(jué)Foundation提供的NSPredicate類(lèi)及其過(guò)濾表達(dá)式特別強(qiáng)大,所以特地去學(xué)習(xí)了下。話不多說(shuō),下面我們來(lái)一起學(xué)習(xí)下吧。
NSPredicate有三個(gè)子類(lèi),如圖是其類(lèi)結(jié)構(gòu)圖

NSPredicate主要用生成基本的條件表達(dá)式,如:
NSMutableArray *array=[NSMutableArray array];
[array addObject:[[Student alloc] initWith:@"lww" age:20]];
[array addObject:[[Student alloc] initWith:@"wy" age:20]];
[array addObject:[[Student alloc] initWith:@"LWW" age:21]];
[array addObject:[[Student alloc] initWith:@"sunshinelww" age:22]];
NSPredicate *basicPredicate=[NSPredicate predicateWithFormat:@"name = 'lww'"];
[array filterUsingPredicate: basicPredicate]; //通過(guò)條件表達(dá)式篩選數(shù)組元素
輸出結(jié)果:

當(dāng)然NSPredicate還可以生成很多復(fù)雜的謂詞表達(dá)式,在此我們不詳細(xì)展開(kāi)。
下面我們來(lái)看下NSCompoundPredicate類(lèi),這個(gè)類(lèi)主要用于組合謂詞表達(dá)式,有三種組合方式:AND,OR和NOT
NSMutableArray *predicateArray=[NSMutableArray array];
NSPredicate *basicPredicate1=[NSPredicate predicateWithFormat:@"name = 'lww'"];
NSPredicate *basicPredicate2=[NSPredicate predicateWithFormat:@"age = 20"];[predicateArray addObject: basicPredicate1];
[predicateArray addObject: basicPredicate2];
NSCompoundPredicate *orMatchPredicate=[NSCompoundPredicate orPredicateWithSubpredicates:predicateArray]; ///對(duì)數(shù)組中的謂詞表達(dá)式取或
NSCompoundPredicate *andMatchPredicate=[NSCompoundPredicate andPredicateWithSubpredicates:predicateArray];///對(duì)數(shù)組中的謂詞表達(dá)式取與
[NSCompoundPredicate notPredicateWithSubpredicate: basicPredicate1]; ///對(duì)basicPredicate1取反
通過(guò)NSCompoundPredicate我們可以靈活實(shí)現(xiàn)多謂詞條件相結(jié)合的方式進(jìn)行過(guò)濾。
最后我們看下NSComparisonPredicate類(lèi)的使用,NSComparisonPredicate主要用來(lái)比較兩個(gè)表達(dá)式的結(jié)果,其中創(chuàng)建NSComparisonPredicate對(duì)象需要指定左表達(dá)式、右表達(dá)式和運(yùn)算符。構(gòu)造方法如下:
- (instancetype)initWithLeftExpression:(NSExpression *)lhs
rightExpression:(NSExpression *)rhs
modifier:(NSComparisonPredicateModifier)modifier
type:(NSPredicateOperatorType)type
options:(NSComparisonPredicateOptions)options;
表達(dá)式類(lèi)為NSExpression,NSExpression分為constant Value和key path等。
其次是操作符枚舉NSPredicateOperatorType,主要有:
typedef NS_ENUM(NSUInteger, NSPredicateOperatorType) {
NSLessThanPredicateOperatorType = 0, // compare: returns NSOrderedAscending
NSLessThanOrEqualToPredicateOperatorType, // compare: returns NSOrderedAscending || NSOrderedSame
NSGreaterThanPredicateOperatorType, // compare: returns NSOrderedDescending
NSGreaterThanOrEqualToPredicateOperatorType, // compare: returns NSOrderedDescending || NSOrderedSame
NSEqualToPredicateOperatorType, // isEqual: returns true
NSNotEqualToPredicateOperatorType, // isEqual: returns false
NSMatchesPredicateOperatorType,
NSLikePredicateOperatorType,
NSBeginsWithPredicateOperatorType,
NSEndsWithPredicateOperatorType,
NSInPredicateOperatorType, // rhs contains lhs returns true
NSCustomSelectorPredicateOperatorType,
NSContainsPredicateOperatorType NS_ENUM_AVAILABLE(10_5, 3_0) = 99, // lhs contains rhs returns true
NSBetweenPredicateOperatorType NS_ENUM_AVAILABLE(10_5, 3_0)
};
通過(guò)指定操作符我們可以對(duì)兩個(gè)表達(dá)式進(jìn)行比較。
該函數(shù)最后一個(gè)參數(shù)是枚舉NSComparisonPredicateOptions用來(lái)指定比較選項(xiàng),定義如下:
typedef NS_OPTIONS(NSUInteger, NSComparisonPredicateOptions) {
NSCaseInsensitivePredicateOption = 0x01, //大小寫(xiě)不敏感
NSDiacriticInsensitivePredicateOption = 0x02, //忽視發(fā)音符號(hào)
NSNormalizedPredicateOption NS_ENUM_AVAILABLE(10_6, 4_0) = 0x04, /* 表示待比較的字符串已經(jīng)被預(yù)處理了。這一選項(xiàng)取代了NSCaseInsensitivePredicateOption和NSDiacriticInsensitivePredicateOption,旨在用作性能優(yōu)化的選項(xiàng) */
};
最后用一個(gè)例子綜合應(yīng)用上述三個(gè)類(lèi)。代碼如下:
NSMutableArray *array=[NSMutableArray array];
[array addObject:[[Student alloc] initWith:@"lww" age:20]];
[array addObject:[[Student alloc] initWith:@"wy" age:20]];
[array addObject:[[Student alloc] initWith:@"LWW" age:21]];
[array addObject:[[Student alloc] initWith:@"sunshinelww" age:22]];
NSExpression *lhs=[NSExpression expressionForKeyPath:@"name"];
NSExpression *rhs=[NSExpression expressionForConstantValue:@"lww"];
NSPredicate *predicate1=[NSComparisonPredicate predicateWithLeftExpression:lhs rightExpression:rhs modifier:NSDirectPredicateModifier type:NSContainsPredicateOperatorType options:0]; //name字符串包含“l(fā)ww”
lhs=[NSExpression expressionForKeyPath:@"age"];
rhs=[NSExpression expressionForConstantValue:@20];
NSPredicate *predicate2=[NSComparisonPredicate predicateWithLeftExpression:lhs rightExpression:rhs modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:NSCaseInsensitivePredicateOption]; //age=20
NSMutableArray *predicateArray=[NSMutableArray array];
[predicateArray addObject:predicate1];
[predicateArray addObject:predicate2];
NSCompoundPredicate *andMatchPredicate=[NSCompoundPredicate andPredicateWithSubpredicates:predicateArray]; //對(duì)兩個(gè)謂詞求與
[array filterUsingPredicate:andMatchPredicate];
for (Student *stu in array) {
[stu printAddress];
}
輸出結(jié)果
