NSPredicate的使用
简述
NSPredicate
谓词条件过滤器,一般用于过滤数组数据,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取。
常用函数
- 创建谓词
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
- 使用谓词过滤集合
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
,包含name
和age
两个属性
初始化数据源数组
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;
}
)