iOS開發-NSPredicate

來源:互聯網
上載者:User

標籤:

Cocoa中謂詞(Predicate)提供了一個通用的查詢方式處理資料,可以擷取和指定資料的過濾形式,Cocoa實際開發中可以是使用NSPredicate及其父類NSComparisonPredicate和NSCompoundPredicate.其風格類似於SQL查詢語言和Regex的混合體,提供了具有表現力的,自然語言介面來定義一個集合被搜尋的邏輯條件。一般來說稍微操作過資料庫基本上很容易理解其中的方法,至於使用的方法也很簡單。

集合中的NSPredicateFoundation提供使用謂詞(predicate)來過濾NSArray/NSMutableArray&NSSet/NSMutableSet的方法。不可變的集合,NSArray&NSSet,可以通過評估接收到的predicate來返回一個不可變集合的方法filteredArrayUsingPredicate和filteredSetUsingPredicate;可變集合,NSMutableArray&NSMutableSet,可以使用方法filterUsingPredicate:可以通過運行接收到的謂詞來移除評估結果為FALSE的對象。

首先來一段比較簡單的代碼: 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", @[@"keso", @"FlyElephant", @"部落格園"]];    if ([predicate evaluateWithObject:@"keso"]) {        NSLog(@"keso");    };

 第一行代碼初始化一個查詢條件,第二句就是判斷資料在不在結果集中,跟SQL基本上一樣,通過IN就能大概瞭解其功能,SELF表示本身,非常常用。

接下來可以類似於SQL中like語句的代碼:

   NSArray *array = [[NSArray alloc]initWithObjects:@"北京",@"上海",@"廣州",@"深圳",nil];    NSPredicate *preBegin= [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@",@"北"];    NSPredicate *preContain= [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"海"];        NSLog(@"%@",[array filteredArrayUsingPredicate:preBegin][0]);    NSLog(@"%@",[array filteredArrayUsingPredicate:preContain][0]);

 第一次就是先初始化數組,然後建立條件,通過filteredArrayUsingPredicate過濾數組;

NSDictionary可以用謂詞來過濾它的鍵和值(兩者都為NSArray對象);

NSOrderedSet可以由過濾的NSArray或NSSet產生一個新的有序的集,或者NSMutableSet可以簡單的removeObjectsInArray來傳遞通過否定predicate過濾的對象。

Core Data中的 NSPredicate

謂詞的在Core Data同樣適用,在管理對象環境中,謂詞由持久化儲存助理(persistent store coordinator)評估,而集合則是記憶體中過濾。這時候我們有必要裡瞭解一下基本比較子:

  • =, ==:左邊的運算式和右邊的運算式相等。
  • >=, =>:左邊的運算式大於或者等於右邊的運算式。
  • <=, =<:左邊的運算式小於等於右邊的運算式。
  • >:左邊的運算式大於右邊的運算式。
  • <:左邊的運算式小於右邊的運算式。
  • !=, <>:左邊的運算式不等於右邊的運算式。
BETWEEN:左邊的運算式等於右邊的運算式的值或者介於它們之間。右邊是一個有兩個指定上限和下限的數值的數列(指定順序的數列)。比如,1 BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。可參考以下代碼:
 NSPredicate *betweenPredicate =    [NSPredicate predicateWithFormat: @"attributeName BETWEEN %@", @[@1, @10]];        NSDictionary *dictionary = @{ @"attributeName" : @5 };        BOOL between = [betweenPredicate evaluateWithObject:dictionary];    if (between) {        NSLog(@"比較子between");    } 
基本複合謂詞
  • AND, &&:邏輯與.
  • OR, ||:邏輯或.
  • NOT, !:邏輯非
字串比較字串比較非常常用,以下的都應該比較熟悉:
  • BEGINSWITH[cd] $FIRST_NAME。
  • BEGINSWITH:左邊的運算式以右邊的運算式作為開始。
  • CONTAINS:左邊的運算式包含右邊的運算式。
  • ENDSWITH:左邊的運算式以右邊的運算式作為結束。
  • LIKE:左邊的運算式等於右邊的運算式:?和*可作為萬用字元,其中?匹配1個字元,*匹配0個或者多個字元。
  • MATCHES:左邊的運算式根據ICU v3的regex風格比較,等於右邊的運算式。
可參考以下代碼:
    NSString *regex = @"[A-Za-z]+";    NSPredicate *matchpredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];        if ([matchpredicate evaluateWithObject:@"keso"]) {        NSLog(@"匹配成功");    }
關係操作
  • 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‘ }。
數組操作
  • array[index]:指定數組中特定索引處的元素。
  • array[FIRST]:指定數組中的第一個元素。
  • array[LAST]:指定數組中的最後一個元素。
  • array[SIZE]:指定數組的大小。
布爾值謂詞
  • TRUEPREDICATE:結果始終為真的謂詞。
  • FALSEPREDICATE:結果始終為假的謂詞。
下面提供一個簡單使用謂詞搜尋類對象的代碼:建立一個People類,標頭檔:
@interface People : NSObject@property (strong,nonatomic) NSString *FirstName;@property (strong,nonatomic) NSString *LastName;@property (nonatomic) NSInteger Height;- (NSString *)description;@end

 People.m檔案:

@implementation People- (NSString *)description {    return  [NSString stringWithFormat:@"%@%@",self.LastName, self.FirstName];};@end

 具體實現代碼:

        NSArray *firstNames =[[NSArray alloc]initWithObjects:@"澤東", @"恩來", @"介石", @"中山", nil];    NSArray *lastNames = @[ @"毛", @"周", @"蔣", @"孫" ];    NSArray *familiar = @[ @100, @99, @99, @98 ];        NSMutableArray *dataList= [NSMutableArray array];    [firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        People *people= [[People alloc] init];        people.FirstName = firstNames[idx];        people.LastName = lastNames[idx];                people.Height= [familiar[idx] integerValue];        [dataList addObject:people];    }];        NSPredicate *firstPredicate = [NSPredicate predicateWithFormat:@"FirstName = ‘恩來‘"];    NSPredicate *lastPredicate = [NSPredicate predicateWithFormat:@"LastName = %@", @"蔣"];    NSPredicate *heightPredicate = [NSPredicate predicateWithFormat:@"Height < 99"];      //名搜尋    NSLog(@"名: %@",[dataList filteredArrayUsingPredicate:firstPredicate][0]);        //姓搜尋    NSLog(@"姓: %@", [dataList filteredArrayUsingPredicate:lastPredicate][0]);        //知名度    NSLog(@"知名度: %@", [dataList filteredArrayUsingPredicate:heightPredicate][0]);

其實開始講的NSCompoundPredicate和NSComparisonPredicate,因為有關係操作,基本上類似,如果通過混合搜尋可以使用and,or實現,比如一下代碼是等價的:

   NSCompoundPredicate *comPredicate=[NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"Height > 90"], [NSPredicate predicateWithFormat:@"FirstName = %@", @"介石"]]];       NSPredicate *secondPredicate=[NSPredicate predicateWithFormat:@"(Height > 90) AND (FirstName = %@)", @"介石"];

  NSComparisonPredicate有兩個調用的靜態方法:

+ (NSComparisonPredicate *)predicateWithLeftExpression:(NSExpression *)lhs rightExpression:(NSExpression *)rhs modifier:(NSComparisonPredicateModifier)modifier type:(NSPredicateOperatorType)type options:(NSComparisonPredicateOptions)options;+ (NSComparisonPredicate *)predicateWithLeftExpression:(NSExpression *)lhs rightExpression:(NSExpression *)rhs customSelector:(SEL)selector;

  其實就是一個運算式的拼接的過程,不過具體的實現蘋果給封裝好了,一下是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)};

參考資料:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-SW1

iOS開發-NSPredicate

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.