NSPredicate
NSPredicate(谓词),可以根据定义的模糊查询条件,对内存对象进行过滤搜索。
基本语法
- 谓词表达式 : 由表达式、运算符和值构成。
- 值:
FALSE、NO:代表逻辑假
TRUE、YES:代表逻辑真
NULL、NIL:代表空值
SELF:代表正在被判断的对象自身
"string"或'string':代表字符串
数组:和c中的写法相同,如:{'one', 'two', 'three'}。
数值:包括证书、小数和科学计数法表示的形式
十六进制数:0x开头的数字
八进制:0o开头的数字
二进制:0b开头的数字-
运算符:
常见用途
1.使用谓词进行正则匹配,例如:
匹配手机号
- (BOOL)checkPhoneNumber:(NSString *)phoneNumber
{
NSString *regex = @"^[1][3-8]\\d{9}$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
return [pred evaluateWithObject:phoneNumber];
}
验证邮箱
+ (BOOL)validateEmail:(NSString *)email{
NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:email];
}
ps:使用正则匹配时,更推荐使用NSRegularExpression而不是NSPredicate,因为NSPredicate对某些表达式的匹配结果并不尽如人意。
正则相关:正则表达式在IOS中的应用
2.使用谓词过滤集合
- NSArray提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合
- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate;
- NSMutableArray提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate;
- NSSet提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSSet集合,返回符合条件的元素组成的新集合
- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate;
- NSMutableSet提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSMutableSet,剔除集合中不符合条件的元素
- (void)filterUsingPredicate:(NSPredicate *)predicate;
- NSOrderedSet提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSOrderedSet集合,返回符合条件的元素组成的新集合
- (NSOrderedSet<ObjectType> *)filteredOrderedSetUsingPredicate:(NSPredicate *)p;
- NSMutableOrderedSet提供了如下方法使用谓词来过滤集合
//使用指定的谓词过滤NSMutableOrderedSet,剔除集合中不符合条件的元素
- (void)filterUsingPredicate:(NSPredicate *)p;
- 以上方法都可以在NSPredicate.h文件中找到。
使用示例:
创建数组,数组中的元素包含name和age两个属性
NSArray *persons = ...
定义谓词对象,谓词对象中包含了过滤条件
(过滤条件中,使用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 IN{30,40}"];
//like 匹配任意多个字符
//name中只要有s字符就满足条件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '*s*'"];
//?代表一个字符,下面的查询条件是:name中第二个字符是s的
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like '?s'"];
使用谓词条件过滤数组中的元素,过滤之后返回查询的结果
NSArray *array = [persons 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];
PS:个人感觉用字符串拼接的方式设置表达式的自由度更高。
网友评论