NSPredicate的使用

简述

NSPredicate谓词条件过滤器,一般用于过滤数组数据,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取。

常用函数

  1. 创建谓词
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
  1. 使用谓词过滤集合
  • NSarray过滤
//使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合
- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate;

  • NSMutableArray过滤
//使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate;

  • NSSet过滤
- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate;

  • NSMutableSet过滤
- (void)filterUsingPredicate:(NSPredicate *)predicate;

  • NSOrderedSet过滤
- (NSOrderedSet<ObjectType> *)filteredOrderedSetUsingPredicate:(NSPredicate *)p;

  • NSMutableOrderedSet过滤
- (void)filterUsingPredicate:(NSPredicate *)p;

使用

创建模型类Person,包含nameage两个属性

初始化数据源数组

	Person *person1 = [Person initWithName:@"alex" andAge:22];
    Person *person2 = [Person initWithName:@"ceciliaba" andAge:35];
    Person *person3 = [Person initWithName:@"1" andAge:42];
    Person *person4 = [Person initWithName:@"otto" andAge:18];
    Person *person5 = [Person initWithName:@"yasha2" andAge:16];
    
    NSArray *personArr = [NSArray arrayWithObjects:person1,person2,person3,person4,person5, nil];

定义谓词对象,设置过滤条件(过滤条件中,使用self.name和直接用name的效果一样)

//age小于30 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age<30"]; 

//查询name=1的并且age大于40 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name='1' && age>40"]; 

//name以a开头的 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'a'"]; 

//name以ba结尾的 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name ENDSWITH 'ba'"]; 

//name为1/2/4,或者age在30-40之间的
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN {'1','2','4'} || age between{30,40}"];
 
//like 匹配任意多个字符 
//name中只要有s字符就满足条件 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '*s*'"]; 

//?代表一个字符,下面的查询条件是:name中第二个字符是s的 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '?s'"]; 

使用谓词条件过滤数组中的元素,过滤之后返回查询的结果

NSArray *array = [personArr filteredArrayUsingPredicate:predicate];  

使用占位符,动态修改条件

在使用时,如果需要拼接属性名,其占位符为%K(注意大写)而不是%@,如:

NSString * key = @"age";
int age = 30;
//拼接示例:
[NSPredicate predicateWithFormat:@"%K < %d", key, age];

如果想动态改变判断的范围,可以使用$ 开头的占位符:

//用$AGE进行占位,可以动态修改$对应的值,这里的AGE可以是任意字符串 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < $AGE"]; 

//修改AGE的值(AGE对应上面的$后的字符串),生成新的NSPredicate对象 
NSPredicate *newPredicate = [predicate predicateWithSubstitutionVariables:@{@"AGE":@30}]; 

//使用newPredicate过滤数组 
NSArray *array = [persons filteredArrayUsingPredicate: newPredicate];

使用附加符号增加规则

附加符号:[c] [d] [cd] c表示不区分大小写,d表示不区分发音字符,cd表示什么都不区分

错误用法

    NSArray *array = [NSArray arrayWithObjects:@{@"city":@"beijing"},@{@"city":@"shanghai"},@{@"city":@"guangzhou"},@{@"city":@"wuhan"}, nil];
    NSString *string = @"ang";

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];
    NSMutableArray *tempArr = [NSMutableArray new];
    for (NSDictionary *dic in array) {
        if ([pred evaluateWithObject:dic[@"city"]]) {
            [tempArr addObject:dic];
        }
    }
    NSLog(@"tempArr = %@",tempArr);

    输出:
    tempArr = (
     {
        city = shanghai;
     },
     {
        city = guangzhou;
     }
     )

这种用法虽然也能过滤出想要的数据,但是效率不高,后面的for循环其实可以省略的
正确用法


    NSPredicate *pred = [NSPredicate predicateWithFormat:@"city CONTAINS[cd] %@",string];
    NSArray *resultArr = [array filteredArrayUsingPredicate:pred];
    NSLog(@"resultArr = %@",resultArr);

    输出:
    resultArr = (
     {
        city = shanghai;
     },
     {
        city = guangzhou;
     }
     )
posted @ 2018-12-20 11:42  大不不  阅读(302)  评论(0编辑  收藏  举报