iOS開發,謂詞(NSPredicate)的用法:(一)基本用法
在iOS開發中,系統提供了NSPredicate這個類給我們進行一些匹配、篩選操作,非常方便。在沒有用這個類時,我們要擷取兩個數組中某些特定的元素時,需要寫代碼一一對比,但是使用了這個類,只需要三四行代碼就夠了。
為了示範,先定義一個person類
.h檔案
#import @interface Person : NSObject@property (nonatomic, copy) NSString *name;@property (nonatomic, assign) NSInteger age;- (instancetype)initWithName:(NSString *)name Age:(NSInteger)age;+(Person *)personWithName: (NSString *)nsme Age: (NSInteger)age;@end
.m檔案
#import "Person.h"@implementation Person- (instancetype)initWithName:(NSString *)name Age:(NSInteger)age { if (self = [super init]) { _name = name; _age = age; } return self;}+ (Person *)personWithName:(NSString *)nsme Age:(NSInteger)age { Person *person = [[Person alloc] initWithName:nsme Age:age]; return person;}- (NSString *)description { return [NSString stringWithFormat:@"name = %@, age = %ld",_name, _age];}@end
我在實現檔案中重寫了description方法,是為了一會在列印篩選結果時能列印出對象屬性的值。
然後將person引入main檔案中(為了方便示範,沒有使用cocoa),建立出10個不同的person對象,並放進數組中。
// 建立出10個person對象,並加入數組 NSMutableArray *muArray = [NSMutableArray array]; for (int i = 0; i <10; i++) { Person *person = [Person personWithName:[NSString stringWithFormat:@"zhang%d",i] Age:i]; [muArray addObject:person]; } NSLog(@"muArray = %@", muArray);
ok,準備工作完成,下邊主角閃亮登場。
NSPredicate使用時主要分兩步走:第一步,定義謂詞語句;第二步,根據要求,選擇不同的方法執行謂詞語句。
首先,我們來定義一個謂詞語句,在定義謂詞語句時,順便會介紹謂詞的文法。
1)比較子
/**比較子 * >:大於 * <:小於 * >=:大於等於 * <=:小於等於 * =,==:等於 * !=,<>:不等於 * between:左邊的運算式等於右邊的運算式的值或者介於它們之間。右邊是一個有兩個指定上限和下限的數值的數列(指定順序的數列)。比如,1 BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。 **/ // 例子:年齡屬性大於3歲,注意:鍵路徑不能用單引號引起來,否則會報錯 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 3"];
2)邏輯運算子
/**邏輯運算子 * and/&&:與 * or/||:或 * not/!:非 **/ // 例子:年齡大於三歲或名字叫“zhang1”的,注意:字串的值需要用單引號引起來,否則會報錯,錯誤資訊是:this class is not key value coding-compliant for the key zhang1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 3 || name = 'zhang1'"];
3)關係運算子
/**關係操作 * ANY,SOME:指定下列運算式中的任意元素。比如,ANY children.age < 18。 * ALL:指定下列運算式中的所有元素。比如,ALL children.age < 18。 * NONE:指定下列運算式中沒有的元素。比如,NONE children.age < 18。它在邏輯上等於NOT (ANY ...)。 * IN:等於SQL的IN操作,左邊的表達必須出現在右邊指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。 **/ // 例子:in關鍵字:左邊的關鍵字裡必須包含右邊的集合的元素 NSPredicate *predicate = [NSPredicate predicateWithFormat:@" name in {'zhang1','zhang4'}"];
4)數組操作
/**數組操作 * array[index]:指定數組中特定索引處的元素。 * array[FIRST]:指定數組中的第一個元素。 * array[LAST]:指定數組中的最後一個元素。 * array[SIZE]:指定數組的大小。 **/
以上就是對謂詞的定義,我們可以看出,我是主要使用了predicateWithFormat:這個類方法進行定義的。
下面進入第二步:執行謂詞語句。
1)、過濾對象是數組:使用- (void)filterUsingPredicate:(NSPredicate *)predicate; 針對可變數組進行過濾,過濾掉可變數組中不合格。- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 針對不可變數組進行過濾,將合格元素組成一個新數組進行返回
2)、對單個對象進行判斷過濾使用:- (BOOL)evaluateWithObject:(id)object; 向謂詞對象發送該方法,參數是過濾的對象。常見於和Regex配合使用。
下邊分別示範上邊的三種方法。
a)、- (void)filterUsingPredicate:(NSPredicate *)predicate; 針對可變數組進行過濾
// 1、建立出10個person對象,並加入數組 NSMutableArray *muArray = [NSMutableArray array]; for (int i = 0; i <10; i++) { Person *person = [Person personWithName:[NSString stringWithFormat:@"zhang%d",i] Age:i]; [muArray addObject:person]; } NSLog(@"muArray = %@", muArray);
// 2、定義謂詞語句:年齡屬性大於3歲,注意:鍵路徑不能用單引號引起來,否則會報錯 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 3"];
// 3、對可變數組進行過濾 [muArray filterUsingPredicate:predicate]; NSLog(@"可變數組過濾後的結果%@", muArray);
我們可以看到列印的結果是:
2015-06-17 11:58:23.126 NSPredicate[3183:277528] 可變數組過濾後的結果( "name = zhang4, age = 4", "name = zhang5, age = 5", "name = zhang6, age = 6", "name = zhang7, age = 7", "name = zhang8, age = 8", "name = zhang9, age = 9")
b)、- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 針對不可變數組進行過濾,將合格元素組成一個新數組進行返回。
// - (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 針對不可變數組進行過濾,將合格元素組成一個新數組進行返回 NSArray *beforeFilterArray = [NSArray arrayWithArray:(NSArray *)muArray]; NSArray *afterFilterArray = [beforeFilterArray filteredArrayUsingPredicate:predicate]; NSLog(@"不可變數組過濾結果%@", afterFilterArray);
我們可以看到列印結果是:
2015-06-17 11:58:23.126 NSPredicate[3183:277528] 不可變數組過濾結果( "name = zhang4, age = 4", "name = zhang5, age = 5", "name = zhang6, age = 6", "name = zhang7, age = 7", "name = zhang8, age = 8", "name = zhang9, age = 9")
c)、- (BOOL)evaluateWithObject:(id)object; 對數組中的每一個元素進行篩選
NSMutableArray *matchObjArray = [NSMutableArray array]; for (Person *item in muArray) { // A、判斷是否滿足條件 // 判斷語句:evaluateWithObject,符合過濾條件就返回yes if ([predicate evaluateWithObject:item]) { [matchObjArray addObject:item]; } } NSLog(@"符合過濾條件的對象是:%@", matchObjArray);
篩選結果是:
2015-06-17 11:58:23.125 NSPredicate[3183:277528] 符合過濾條件的對象是:( "name = zhang4, age = 4", "name = zhang5, age = 5", "name = zhang6, age = 6", "name = zhang7, age = 7", "name = zhang8, age = 8", "name = zhang9, age = 9")
小結:以上三種方法都可以執行謂詞短語,如果是對數組元素進行過濾的話,我們使用:- (void)filterUsingPredicate:(NSPredicate *)predicate、- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;更方便,如果是只針對一個對象進行判斷的話,使用- (BOOL)evaluateWithObject:(id)object; 更方便。