NSPredict

来源:互联网 发布:mac上photoshop 编辑:程序博客网 时间:2024/05/17 07:39

参考:

http://justsee.iteye.com/blog/1816971

http://nshipster.cn/nspredicate/

http://blog.csdn.net/ztp800201/article/details/8116081

谓词语法

替换

%@是对值为字符串,数字或者日期的对象的替换值。
%K是key path的替换值。
NSPredicate *ageIs33Predicate = [NSPredicate predicateWithFormat:@"%K = %@", @"age", @33];  // ["Charlie Smith"] NSLog(@"Age 33: %@", [people filteredArrayUsingPredicate:ageIs33Predicate]); 

$VARIABLE_NAME是可以被NSPredicate -predicateWithSubstitutionVariables:替换的值。
NSPredicate *namesBeginningWithLetterPredicate = [NSPredicate predicateWithFormat:@"(firstName BEGINSWITH[cd] $letter) OR (lastName BEGINSWITH[cd] $letter)"]; // ["Alice Smith", "Quentin Alberts"] NSLog(@"'A' Names: %@", [people filteredArrayUsingPredicate:[namesBeginningWithLetterPredicate predicateWithSubstitutionVariables:@{@"letter": @"A"}]]);

基本比较

=, ==:左边的表达式和右边的表达式相等。
>=, =>:左边的表达式大于或者等于右边的表达式。
<=, =<:左边的表达式小于等于右边的表达式。
>:左边的表达式大于右边的表达式。
<:左边的表达式小于右边的表达式。
!=, <>:左边的表达式不等于右边的表达式。
 
BETWEEN:左边的表达式等于右边的表达式的值或者介于它们之间。右边是一个有两个指定上限和下限的数值的数列(指定顺序的数列)。比如,1 BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。
 

基本复合谓词

AND, &&:逻辑与.
OR, ||:逻辑或.
NOT, !:逻辑非.
 

字符串比较

字符串比较在默认的情况下是区分大小写和音调的。你可以在方括号中用关键字符c和d来修改操作符以相应的指定不区分大小写和变音符号,比如firstname BEGINSWITH[cd] $FIRST_NAME。
BEGINSWITH:左边的表达式以右边的表达式作为开始。
CONTAINS:左边的表达式包含右边的表达式。
ENDSWITH:左边的表达式以右边的表达式作为结束。
LIKE:左边的表达式等于右边的表达式:?和*可作为通配符,其中?匹配1个字符,*匹配0个或者多个字符。
MATCHES:左边的表达式根据ICU v3(更多内容请查看ICU User Guide for Regular Expressions)的regex风格比较,等于右边的表达式。
 

合计操作

关系操作

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:结果始终为假的谓词。

NSCompoundPredicate

我们见过与&或被用在谓词格式字符串中以创建复合谓词。然而,我们也可以用NSCompoundPredicate来完成同样的工作。
[NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"age > 25"], [NSPredicate predicateWithFormat:@"firstName = %@", @"Quentin"]]]; 
等效于
[NSPredicate predicateWithFormat:@"(age > 25) AND (firstName = %@)", @"Quentin"]; 

虽然语法字符串文字更加容易输入,但是在有的时候,你需要结合现有的谓词。在那些情况下,你可以使用NSCompoundPredicate -andPredicateWithSubpredicates:&-orPredicateWithSubpredicates:。
既然都一样,为什么要有 在NSPredict的官方文档中讲到

The disadvantage of this technique should be immediately apparent—you may have to write a lot of code.

The advantages are that it is less prone to spelling and other typographical errors that may only be discovered

at runtime and it may be faster than depending on string parsing.

This technique is most likely to be useful when the creation of the predicate is itself dynamic, such as in a

predicate builder.

NSComparisonPredicate

就像NSCompoundPredicate一样,NSComparisonPredicate从子部件构建了一个NSPredicate--在这种情况下,左侧和右侧都是NSExpression。 分析它的类的构造函数可以让我们一窥NSPredicate的格式字符串是如何解析的:
+ (NSPredicate *)predicateWithLeftExpression:(NSExpression *)lhs                              rightExpression:(NSExpression *)rhs                                     modifier:(NSComparisonPredicateModifier)modifier                                         type:(NSPredicateOperatorType)type                                      options:(NSUInteger)options 

参数
lhs:左边的表达式。
rhs:右边的表达式。
modifier:应用的修改符。(ANY或者ALL)
type:谓词运算符类型。
options:要应用的选项。没有选项的话则为0。

NSComparisonPredicate类型

enum {    NSLessThanPredicateOperatorType = 0,    NSLessThanOrEqualToPredicateOperatorType,    NSGreaterThanPredicateOperatorType,    NSGreaterThanOrEqualToPredicateOperatorType,    NSEqualToPredicateOperatorType,    NSNotEqualToPredicateOperatorType,    NSMatchesPredicateOperatorType,    NSLikePredicateOperatorType,    NSBeginsWithPredicateOperatorType,    NSEndsWithPredicateOperatorType,    NSInPredicateOperatorType,    NSCustomSelectorPredicateOperatorType,    NSContainsPredicateOperatorType,    NSBetweenPredicateOperatorType }; typedef NSUInteger NSPredicateOperatorType; 

NSComparisonPredicate选项
NSCaseInsensitivePredicateOption:不区分大小写的谓词。你通过在谓词格式字符串中加入后面带有[c]的字符串操作(比如,"NeXT" like[c] "next")来表达这一选项。
 
NSDiacriticInsensitivePredicateOption:忽视发音符号的谓词。你通过在谓词格式字符串中加入后面带有[d]的字符串操作(比如,"naïve" like[d] "naive")来表达这一选项。
 
NSNormalizedPredicateOption:表示待比较的字符串已经被预处理了。这一选项取代了NSCaseInsensitivePredicateOption和NSDiacriticInsensitivePredicateOption,旨在用作性能优化的选项。你可以通过在谓词格式字符串中加入后面带有[n]的字符串(比如,"WXYZlan" matches[n] ".lan")来表达这一选项。
 
NSLocaleSensitivePredicateOption:表明要使用<,<=,=,=>,> 作为比较的字符串应该使用区域识别的方式处理。你可以通过在<,<=,=,=>,>其中之一的操作符后加入[l](比如,"straße" >[l] "strasse")以便在谓词格式字符串表达这一选项。

Block谓词

最后,如果你实在不愿意学习NSPredicate的格式语法,你也可以学学NSPredicate +predicateWithBlock:。
  1. NSPredicate *shortNamePredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
  2.             return [[evaluatedObject firstName] length] <= 5; 
  3.         }]; 
  4.  
  5. // ["Alice Smith", "Bob Jones"] 
  6. NSLog(@"Short Names: %@", [people filteredArrayUsingPredicate:shortNamePredicate]); 
...好吧,虽然使用predicateWithBlock:是懒人的做法,但它也并不是一无是处。
 
事实上,因为block可以封装任意的计算,所以有一个查询类是无法以NSPredicate格式字符串形式来表达的(比如对运行时被动态计算的值的评估)。而且当同一件事情可以用NSExpression结合自定义选择器来完成时,block为完成工作提供了一个方便的接口。
重要提示:由predicateWithBlock:生成的NSPredicate不能用于由SQLite存储库支持的Core Data数据的提取要求。

初始化NSPredicate

- (void)learnNSPredictAgain{    NSString *testStr = @"13200000089";    NSString *phoneRegex = @"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$";    // 1.predicateWithFormat    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];        if ([predicate evaluateWithObject:testStr]) {        NSLog(@"yes");    }        // 2.predicateWithFormat argument    NSPredicate *predictWithArgumentArray = [NSPredicate predicateWithFormat:@"SELF MATCHES %@" argumentArray:@[phoneRegex]];    if ([predictWithArgumentArray evaluateWithObject:testStr]) {        NSLog(@"yes");    }    // 3.predicateWithFormat argument    [self evaluateObject:testStr predictWithArgList:@"%@", phoneRegex];        // 4.predicateWithValue  value 为YES时 evaluateWithObject返回始终都是YES    NSPredicate *predicateWithValue = [NSPredicate predicateWithValue:YES];    if ([predicateWithValue evaluateWithObject:testStr]) {        NSLog(@"YES");    }        // 如果你不想写正则表达式的话    NSString *name = @"abbbsbsba";    NSPredicate *predicateWithBlock = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {        if (evaluatedObject) {            if ([evaluatedObject isKindOfClass:[NSString class]]) {                NSString *evaluateStr = (NSString *)evaluatedObject;                NSRange range = [evaluateStr rangeOfString:bindings[@"regx"]];                if (range.location != NSNotFound) {                    return YES;                }            }        }        return NO;    }];    if ([predicateWithBlock evaluateWithObject:name substitutionVariables:@{@"regx":@"a"}]) {        NSLog(@"YES");    }    // 数组的过滤方式    NSArray *array = @[@"jwij", @"ss", @"wejf", @"322ds"];//    NSPredicate *predicateArray = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] 's'"];    NSPredicate *predicateArray = [NSPredicate predicateWithFormat:@"SELF CONTAINS 's'"];    NSArray *resultArray = [array filteredArrayUsingPredicate:predicateArray];    NSLog(@"resultArray:%@", resultArray);}-(void) evaluateObject:(id)obj predictWithArgList:(NSString *)format,...{    if (format) {        va_list arguments;        va_start(arguments, format);        va_end(arguments);        NSPredicate *phoneTest2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@" arguments:arguments];        if ([phoneTest2 evaluateWithObject:obj]) {            NSLog(@"yes");        }    }}

对于Model怎么用Predict

@interface Job : NSObject@property (nonatomic, strong) NSString *name;@end#import <Foundation/Foundation.h>#import "Job.h"@interface Person : NSObject@property (nonatomic, strong) NSString *firstName;@property (nonatomic, strong) NSString *lastName;@property (nonatomic, strong) NSNumber *age;@property (nonatomic, strong) Job *job;@end

NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan", nil];    NSString *string = @"ang";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];//    NSPredicate *pred = [NSPredicate predicateWithValue:NO];    NSLog(@"%@",[array filteredArrayUsingPredicate:pred]);        NSArray *firstNames = @[ @"Alice", @"Bob", @"Charlie", @"Quentin" ];    NSArray *lastNames = @[ @"Smith", @"Jones", @"Smith", @"Alberts" ];    NSArray *ages = @[ @24, @27, @33, @31 ];     NSArray *jobs = @[ @"teacher", @"engineer", @"boss", @"manager" ];     NSMutableArray *mJobs = [NSMutableArray array];    [jobs enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        Job *job = [[Job alloc] init];        job.name = jobs[idx];        [mJobs addObject:job];    }];    NSMutableArray *people = [NSMutableArray array];    [firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {        Person *person = [[Person alloc] init];        person.firstName = firstNames[idx];        person.lastName = lastNames[idx];        person.age = ages[idx];        person.job = mJobs[idx];        [people addObject:person];    }];        NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];    NSPredicate *smithPredicate = [NSPredicate predicateWithFormat:@"lastName = %@", @"Smith"];    NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];    NSPredicate *keyPathPredict = [NSPredicate predicateWithFormat:@"job.name contains [cd] 'boss'"];    NSPredicate *inPredict = [NSPredicate predicateWithFormat:@"firstName IN {'Alice', 'Bob'}"];        // ["Bob Jones"]    NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);        // ["Alice Smith", "Charlie Smith"]    NSLog(@"Smiths: %@", [people filteredArrayUsingPredicate:smithPredicate]);        // ["Charlie Smith", "Quentin Alberts"]    NSLog(@"30's: %@", [people filteredArrayUsingPredicate:thirtiesPredicate]);        // ["manager", "Quentin Alberts"]    NSLog(@"manager: %@", [people filteredArrayUsingPredicate:keyPathPredict]);        // inPredict    NSLog(@"inPredict: %@", [people filteredArrayUsingPredicate:inPredict]);        // %@是对值为字符串,数字或者日期的对象的替换值    // %K是key path的替换值。    NSPredicate *ageIs33Predicate = [NSPredicate predicateWithFormat:@"%K = %@", @"age", @33];        // ["Charlie Smith"]    NSLog(@"Age 33: %@", [people filteredArrayUsingPredicate:ageIs33Predicate]);        //    NSPredicate *alicePredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {        Person *person = (Person *)evaluatedObject;        if ([person.firstName isEqualToString:@"Alice"]) {            return YES;        }        return NO;    }];    NSLog(@"find Alice:%@", [people filteredArrayUsingPredicate:alicePredicate]);        // predicateWithSubstitutionVariables:    NSPredicate *namesBeginningWithLetterPredicate = [NSPredicate predicateWithFormat:@"(firstName BEGINSWITH[cd] $letter) OR (lastName BEGINSWITH[cd] $letter)"];        // ["Alice Smith", "Quentin Alberts"]    NSLog(@"'A' Names: %@", [people filteredArrayUsingPredicate:[namesBeginningWithLetterPredicate predicateWithSubstitutionVariables:@{@"letter": @"A"}]]);        NSPredicate *compoundP = [NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"age > 25"], [NSPredicate predicateWithFormat:@"firstName = %@", @"Quentin"]]];    NSArray *compoundArray = [people filteredArrayUsingPredicate:compoundP];    NSPredicate *predictAnd = [NSPredicate predicateWithFormat:@"(age > 25) AND (firstName = %@)", @"Quentin"];    NSArray *predictAndArray = [people filteredArrayUsingPredicate:predictAnd];    NSLog(@"compoundArray:%@,predictAndArray:%@", compoundArray, predictAndArray);




0 0
原创粉丝点击