必威NSPredicate 为开发再快捷。NSPredicate

图表源于网络.jpg

一、简介

NSPredicate指定数量为获取或者过滤的措施,是一个Foundation类。

Cocoa框架中的NSPredicate用于指定过滤器的口径(即查询),它的法则和用法都像SQL的WHERE和正则表达式一样,作用相当给数据库的过滤器

最常用到的函数:+ predicateWithFormat: 创建谓词串

+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;

NSPredicate *predicate  = [NSPredicate predicateWithFormat:@"name == 'Herbie'"];

//注意:如果谓词串中的文本块未被引用,则被看做是键路径,即需要用引号表明是字符串,单引号,双引号均可.键路径可以在后台包含许多强大的功能

NSPredicate是一个Foundation类,它指定数量为获取或者过滤的主意。它的询问语言就如SQL的WHERE和正则表达式的陆续一样,提供了富有表现力的,自然语言界面来定义一个集结被摸的逻辑条件。

名叫词语法

范例数据源:

索引 0 1 2 3
Alice Bob Charlie Quentin
Smith Jones Smith Alberts
年龄 24 27 33 31

背景:

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *age;
@end

NSArray *firstNames = @[ @"Alice", @"Bob", @"Charlie", @"Quentin" ];
NSArray *lastNames = @[ @"Smith", @"Jones", @"Smith", @"Alberts" ];
NSArray *ages = @[ @24, @27, @33, @31 ];

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];
    [people addObject:person];
}];

NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];
NSPredicate *smithPredicate = [NSPredicate predicateWithFormat:@"lastName = %@", @"Smith"];
NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];

// ["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]);

一、NSPredicate 使用

1.替换

为便利,多数无行使替换,而是一直输入 key path 、对象 和
$VARIABLE_NAME 。

  • %@是本着价吗字符串,数字还是日期的靶子的交替值。
  • %K是key path的轮换值。
  • $VARIABLE_NAME 是得给 NSPredicate
    -predicateWithSubstitutionVariables: 替换的价值。
NSPredicate *ageIs33Predicate = [NSPredicate predicateWithFormat:@"%K = %@", @"age", @33];
//为了简便,也写作:@"age = 33"
NSLog(@"Age 33: %@", [people filteredArrayUsingPredicate:ageIs33Predicate]);
//运行结果: ["Charlie Smith"]

NSPredicate *namesBeginningWithLetterPredicate = [NSPredicate predicateWithFormat:@"(firstName BEGINSWITH[cd] $letter) OR (lastName BEGINSWITH[cd] $letter)"];
//为了简便,也写作:@"(firstName BEGINSWITH[cd] 'A') OR (lastName BEGINSWITH[cd] 'A')"
NSLog(@"'A' Names: %@", [people filteredArrayUsingPredicate:[namesBeginningWithLetterPredicate predicateWithSubstitutionVariables:@{@"letter": @"A"}]]);
// 运行结果:["Alice Smith", "Quentin Alberts"]
(1)集合中使用NSPredicate

NSArray&NSSet,不可变的会师,有足通过评估接收及的predicate来回到一个不可变集合的不二法门filteredArrayUsingPredicate:和filteredSetUsingPredicate:。

NSMutableArray&NSMutableSet,可转换集合,可以采用方法filterUsingPredicate:,它好通过运行接收到的称呼词来移除评估结果吗FALSE的对象。

2. 着力比较:比较运算符

  • =, ==:左右对等。
  • =, =>:大于或者当。

  • <=, =<:小于等于。

  • <

  • !=, <>:不等于。
  • BETWEEN:左边的表达式等于右边的表达式的值或者在它们中。

右边是一个生有限单指定上限和下限的数值的数列(指定顺序的数列)。

比如,1 BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"number BETWEEN {1,5}"];
(2)配合正则表达式使用
-(BOOL)checkPhoneNumber:(NSString *)phoneNumber{
    NSString *regex = @"^[1][3-8]\\d{9}$";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pred evaluateWithObject:phoneNumber];
}

3.字符串比较

字符串比较在默认的状态下是分别轻重缓急写及声腔的。在方括号中之所以要字符c和d来窜操作,比如firstname
BEGINSWITH[cd] $FIRST_NAME。

[c]莫分轻重缓急写 , [d]切莫分发音符号即无重音符号 ,
[cd]既然如此未分轻重缓急写,也非分发音符号。

  • BEGINSWITH:左边的表达式以右手边的表达式作为开
  • CONTAINS:左边的表达式包含右边的表达式
  • ENDSWITH:左边的表达式以右手边的表达式作为完结
  • LIKE:左边的表达式等于右边的表达式:?和* 可当连接配符,其中
    ?匹配1独字符,*匹配配0个或基本上单字符。
  • MATCHES:正则表达式:左边的表达式根据ICU v3(更多内容请查看ICU
    User Guide for Regular
    Expressions)的regex风格比较,等于右边的表达式。
  • SELF :字符串本身,例:@”SELF == ‘APPLE’ “
//name 均是对象的属性
[NSPredicate predicateWithFormat:@"name CONTAINS[cd] 'xxx'"];   //包含某个(xxx)字符串 

[NSPredicate predicateWithFormat:@"name BEGINSWITH[c] 'xxx'"];     //以某个字符串开头    

[NSPredicate predicateWithFormat:@"name ENDSWITH[d] 'xxx'"];      //以某个字符串结束

[NSPredicate predicateWithFormat:@"name LIKE[cd] '*er*'"];     //*代表通配符,Like也接受[cd].     
[NSPredicate predicateWithFormat:@"name LIKE[cd] '???er*'"]; 

NSString *regex = @"^A.+e$";   //以A开头,e结尾
[NSPredicate predicateWithFormat: @"name MATCHES %@",regex];      

//在数组筛选中,如果我不想用任何实例方法,想筛选成员本身时,可以用self来代替
NSArray *array = @[@"jim", @"cook", @"jobs", @"APPLE"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF == 'APPLE'"];
NSLog(@"%@", [array filteredArrayUsingPredicate:pre]);
(3)Core Data中使用NSPredicate

NSFetchRequest有一个predicate属性,它可以指定管理对象应该为获之逻辑条件。谓词的采用规则以此同样适用,唯一的区分在于,在管理对象环境受到,谓词由持久化存储助理(persistent
store coordinator)评估,而无像集合那样以内存中叫过滤。

self.studentArray
添加200独数据,供筛选,以下是生成self.studentArray的代码

// 学生对象
@interface Student :NSObject
/** 名字 */
@property (nonatomic, strong) NSString *name;
/** 班级 */
@property (nonatomic, assign) NSUInteger class;
/** 分数 */
@property (nonatomic, assign) NSUInteger score;

- (instancetype)initWithName:(NSString *)name Class:(NSInteger)class Score:(NSInteger)score;
@end
@implementation Student

- (instancetype)initWithName:(NSString *)name
                       Class:(NSInteger)class
                       Score:(NSInteger)score{
    if (self = [super init]) {
        if (class > 6 || class < 1) class = 1;
        if (score > 100 || score < 0) score = 0;
        _name = name;
        _class = class;
        _score = score;
    }
    return self;
}

@end

@interface ViewController ()
@property (nonatomic, strong) NSMutableArray <Student *> *studentArray;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}
#pragma mark - - lazy load

- (NSMutableArray<Student *> *)studentArray{
    if (!_studentArray) {
        _studentArray = [NSMutableArray arrayWithCapacity:0];
        for (int i = 0; i < 200; i ++) {
            NSString *name = [self randomStringWithLength:5];
            NSInteger score = arc4random() % 100;
            NSInteger class = arc4random() % 6;

            Student *student = [[Student alloc] initWithName:name
                                                       Class:class
                                                       Score:score];
            [_studentArray addObject:student];
        }
    }
    return _studentArray;
}


/** 获取随机字符串 */
- (NSString *)randomStringWithLength:(NSInteger)length{
    char data[length];
    for (int x=0;x<length;data[x++] = (char)('a' + (arc4random_uniform(26))));
    return [[NSString alloc] initWithBytes:data length:length encoding:NSUTF8StringEncoding];
}

@end

4. 核心复合谓词

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

次、谓词语法

5. 商谈操作

(1)替换

  • %@ 是本着价吗字符串,数字还是日期的目标的替换值。
  • %K 是key path的交替值。
  • $VARIABLE_NAME 是好吃NSPredicate
    -predicateWithSubstitutionVariables:替换的值。
    //(%K,%d =\== 使用)
    // 分数为满分
    NSPredicate *predicateA = [NSPredicate predicateWithFormat:@"%K = %d",@"score",100];
    NSArray *caseA = [self.studentArray filteredArrayUsingPredicate:predicateA];

    //(self、BEGINSWITH、[]、$ 使用)
    // 名字以 ‘a’开头
    NSPredicate *predicateB = [NSPredicate predicateWithFormat:@"self.name BEGINSWITH[az] $beginningChar"];
    NSArray *caseB = [self.studentArray filteredArrayUsingPredicate:[predicateB predicateWithSubstitutionVariables:@{@"beginningChar": @"a"}]];

5.1 关系操作

  • 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’ }。

(2)比较运算符

  • =, == :左边的表达式和右手的表达式相等。
  • >=, => :左边的表达式大于或者当右边的表达式。
  • <=, =< :左边的表达式小于等于右边的表达式。
  • > :左边的表达式大于右边的表达式。
  • < :左边的表达式小于右边的表达式。
  • !=, <> :左边的表达式不齐右边的表达式。
  • BETWEEN
    :左边的表达式等于右边的表达式的价或者在它们之间。右边是一个有三三两两只指定上限和下限的数值的数列(指定顺序的数列)。比如,1
    BETWEEN { 0 , 33 },或者$INPUT BETWEEN { $LOWER, $UPPER }。
// 比较运算符 =, ==  >=, =>  <=, =< > < !=, <> BETWEEN 使用
    // 90~100 优等学生
    NSPredicate *predicateC = [NSPredicate predicateWithFormat:@"self.score BETWEEN {90,100}"];
    NSArray *caseC = [self.studentArray filteredArrayUsingPredicate:predicateC];

5.2 数组操作

  • array[index]:指定数组中一定索引处的素。
  • array[FIRST]:指定数组中的率先单要素。
  • array[LAST]:指定数组中之结尾一个元素。
  • array[SIZE]:指定数组的高低。

(3)逻辑运算符

  • AND, && :逻辑与
  • OR, || :逻辑或
  • NOT, ! :逻辑非
    // 逻辑运算符 AND, && :逻辑与 OR, || :逻辑或 NOT, ! :逻辑非
    // 名字以 ‘a’开头 并 及格的学生
    NSPredicate *predicateD = [NSPredicate predicateWithFormat:@"self.score >= 60 AND self.name BEGINSWITH[az] 'a'"];
    NSArray *caseD = [self.studentArray filteredArrayUsingPredicate:predicateD];

5.3 布尔值谓词

  • TRUEPREDICATE:结果一直为实在谓词。
  • FALSEPREDICATE:结果始终为假的谓词

(4)字符串比较运算符

字符串比较在默认的图景下是分别轻重缓急写及腔调的。你可以方括号丁之所以要字符c和d来改操作符以相应的指定不区分轻重缓急写及变音符号,比如firstname
BEGINSWITH[cd] $FIRST_NAME。

  • BEGINSWITH :左边的表达式以右手边的表达式作为开头。
  • CONTAINS :左边的表达式包含右边的表达式。
  • ENDSWITH :左边的表达式以右手边的表达式作为完结。
  • LIKE :左边的表达式等于右边的表达式:?和*然而看成过渡配符,其中?
    匹配1独字符,* 匹配0个或基本上个字符。
  • MATCHES :左边的表达式根据ICU v3
    的regex风格比较,等于右边的表达式。
// 字符串比较运算符 BEGINSWITH 、CONTAINS、ENDSWITH、LIKE、MATCHES
    NSPredicate *predicateE = [NSPredicate predicateWithFormat:@"self.name like 'a*c*'"];
    NSArray *caseE = [self.studentArray filteredArrayUsingPredicate:predicateE];

其三、应用场景

(5)集合运算符

必威论及操作

  • 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’ }。

1. 集结中动用NSPredicate

Foundation提供使用谓词(predicate)来过滤NSArray/NSMutableArray&NSSet/NSMutableSet的不二法门。

本着不可变的聚众(NSArray&NSSet),通过评估接收至之predicate,用
filteredArrayUsingPredicate:filteredSetUsingPredicate:
方法来回到一个不可变集合:

filteredArrayUsingPredicate:
是NSArray数组的同一栽档次方法,循环过滤数组中的情节,将值为YES的目标累积至结果数组中归。

//对NSArray进行过滤 
NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan", nil];    
NSString *string = @"ang";    
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];    
NSLog(@"%@",[array filteredArrayUsingPredicate:pred]); 

(6)直接量

每当号称词表达式中可运用如下直接量

  • FALSE、NO:代表逻辑假
  • TRUE、YES:代表逻辑真
  • NULL、NIL:代表空值
  • SELF:代表着给判定的靶子自我
  • “string”或’string’:代表字符串
  • 数组:和c中的写法相同,如:{‘one’, ‘two’, ‘three’}。
  • 数值:包括证明、小数和科学计数法表示的形式
  • 十六上前制数:0x开头的数字
  • 八进制:0o开头的数字
  • 次进制:0b上马的数字

2.模子中使NSPredicate — 由汇拓展及范

利用成员实例方法(集合中成员的方法) 拓展到
利用成员方法(集合中对象的属性的方法)

罗产生数组成员方法[people firstName]返回值 = ‘Bob’ 的成员。

NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];

// ["Bob Jones"]
NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);

(7)数组操作

  • array[index] :指定数组中一定索引处的元素。
  • array[FIRST] :指定数组中的率先单要素。
  • array[LAST] :指定数组中之末梢一个元素。
  • array[SIZE] :指定数组的轻重。

3.大抵复筛选NSCompoundPredicate

一经急需般配数独特性的淘,用AND或者OR来串联显然不怎么麻烦。

NSCompoundPredicate类可以满足我们的要求,它可拿大半个NSPredicate对象的组成,组合措施得以是AND或者OR

andPredicateWithSubpredicates:    orPredicateWithSubpredicates:

   NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"code >= %@", @3];
    NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"code <= %@", @2];
    //以AND形式组合
    NSPredicate *pre = [NSCompoundPredicate andPredicateWithSubpredicates:@[pre1,pre2]];
    //以OR形式组合
    NSPredicate *pre = [NSCompoundPredicate orPredicateWithSubpredicates:@[pre1, pre2]];

(8)布尔值谓词

  • TRUEPREDICATE :结果一直为真正谓词。
  • FALSEPREDICATE :结果总为假的谓词。

(9)Block谓词

NSPredicate *shortNamePredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            return [[evaluatedObject firstName] length] <= 5;
        }];
NSLog(@"Short Names: %@", [people filteredArrayUsingPredicate:shortNamePredicate]);

相关文章