文章目录
- NSPredicate 简述
- 使用示例
- 一、过滤数值
- 1、判断数值相等、大小等
- 2、判断数值范围 Between
- 二、过滤字符串
- 1、BEGINSWITH:是否以指定字符串开头
- 2、ENDSWITH:是否以指定字符串结尾
- 3、CONTAINS:是否包含指定字符串
- 4、LIKE & ?:是否匹配指定字符串模板
- 4.1 `?` 代表一个字符
- 4.2* 代表任意多个字符
- 5、MATCHES:是否匹配指定的正则表达式
- 6、字符串比较都是区分大小写和重音符号的。
- 7、IN 运算
- AND(或&&)
- 三、过滤数组、Set
- 0、过滤方法
- 过滤 NSArray:`filteredArrayUsingPredicate:`
- NSMutableArray:`filterUsingPredicate:`
- NSSet `filteredSetUsingPredicate:`
- NSMutableSet `filterUsingPredicate:`
- 1、数值数组筛选
- 2、字符串数组的筛选
- 3、取两个数组的交集
- 4、过滤模型数组
- predicateWithSubstitutionVariables
- 参考资料
NSPredicate 简述
NSPredicate类是一种过滤器,用来定义 逻辑条件约束的获取 或 内存中的。
在别写 NSPredicate 语句的时候,可以使用
- 比较运算符: 大于等于 >=,=>, 小于等于<=,=<,不等于!=、<>, 相等 =;
- 逻辑运算符(与或非)AND、&&;OR、||;NOT、 !;
- 字符串比较运算符:BEGINSWITH、ENDSWITH、CONTAINS、LIKE
- 集合运算符:ANY、SOME、ALL、NONE、IN
- 直接量:FALSE、NO;TRUE、YES;NULL、NIL;SELF、"string"或’string’;数组,如:{‘one’, ‘two’, ‘three’}(和c中的写法相同);数值、十六进制数:0x开;八进制:0o开头;二进制:0b开头的数字。
- 保留字:AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE
使用示例
一、过滤数值
是否复合某个条件,返回BOOL,使用方法如:
下面例子,都是用下面数值做测试:
NSNumber *num0 = @123;
NSNumber *num1 = @1234;
NSString *str0 = @"123";
1、判断数值相等、大小等
- =、:判断两个表达式是否相等,在谓词中=和是相同的意思都是判断,而没有赋值这一说;
- 字符串不能使用 = 判断;
NSNumber *num0 = @123;
NSNumber *num1 = @1234;
NSString *str0 = @"123";
NSPredicate *pre0 = [NSPredicate predicateWithFormat:@"SELF = 123"];
NSLog(@"%d",[pre0 evaluateWithObject:num0]);//1
NSLog(@"%d",[pre0 evaluateWithObject:num1]);//0
NSLog(@"%d",[pre0 evaluateWithObject:str0]);//0
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF > 1000"];
NSLog(@"%d",[pre1 evaluateWithObject:num0]);//1
NSLog(@"%d",[pre1 evaluateWithObject:num1]);//0
2、判断数值范围 Between
- 表达式 BETWEEN {下限,上限}的格式,要求该表达式必须大于或等于下限,并小于或等于上限
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];
NSLog(@"%d",[pre2 evaluateWithObject:num0]);//1
NSLog(@"%d",[pre2 evaluateWithObject:num1]);//0
二、过滤字符串
1、BEGINSWITH:是否以指定字符串开头
如:判断字符串是否以a开头:BEGINSWITH ‘a’)
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH 'a'"];
NSLog(@"%d",[pre evaluateWithObject:@"ab"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"abc"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"ba"]);//0
2、ENDSWITH:是否以指定字符串结尾
如:判断字符串是否以ba结尾:ENDSWITH ‘ba’)
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF ENDSWITH 'ba'"];
NSLog(@"%d",[pre evaluateWithObject:@"ab"]);//0
NSLog(@"%d",[pre evaluateWithObject:@"abc"]);//0
NSLog(@"%d",[pre evaluateWithObject:@"ba"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"cba"]);//1
3、CONTAINS:是否包含指定字符串
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'jo'"];
NSLog(@"%d",[pre evaluateWithObject:@"John"]);//0
NSLog(@"%d",[pre evaluateWithObject:@"john"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"Milly"]);//0
4、LIKE & ?:是否匹配指定字符串模板
其之后可以跟?代表一个字符和*代表任意多个字符两个通配符。
4.1 ?
代表一个字符
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF LIKE '?ng'"];
NSLog(@"%d",[pre evaluateWithObject:@"png"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"jpng"]);//0
4.2* 代表任意多个字符
样式类似 前缀为 ang
,后面跟随其他字符:
NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF LIKE 'ang*'"];
NSLog(@"%d",[pre evaluateWithObject:@"ango"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"angel"]);//1
NSLog(@"%d",[pre evaluateWithObject:@"jiang"]);//0
上面条件,angle和lenang都符合;
你也可以把 * 放到 ang
前面。
5、MATCHES:是否匹配指定的正则表达式
虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。
- (void)checkPhoneNumber
{
NSString *regex = @"^[1][3-8]\\d{9}$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
NSLog(@"%d", [pred evaluateWithObject:@"15818663297"]);//1
NSLog(@"%d", [pred evaluateWithObject:@"303178203"]);//0
}
6、字符串比较都是区分大小写和重音符号的。
如:café和cafe是不一样的,Cafe和cafe也是不一样的。判断时可以加上下面符号进行区分:
[c] 忽略大小写;
[d] 忽略重音符号;比如:name LIKE[cd] ‘cafe’,那么不论name是cafe、Cafe还是café上面的表达式都会返回YES。
[cd]既不区分大小写,也不区分发音符号。
NSArray *stringArray = @[@"John",@"john",@"Jolly",@"Milly"];
NSString *targetString = @"jo";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@",targetString];
NSLog(@"%@",[stringArray filteredArrayUsingPredicate:pred]);// John,john,Jolly
7、IN 运算
对于 NSString类型,判断title属性是否是字符串@"angle"和@"addss"中的一个:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF IN {'angle', 'addss'}"];
NSLog(@"%d", [pred evaluateWithObject:@"angle"]);//1
NSLog(@"%d", [pred evaluateWithObject:@"blue"]);//0
对于 NSNumber类型,判断testID属性是否是NSNumber对象中的@1和@13中的一个:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF IN {1, 13}"];
NSLog(@"%d", [pred evaluateWithObject:@(13)]);//1
NSLog(@"%d", [pred evaluateWithObject:@(5)]);//0
AND(或&&)
NSPredicate *pred = [NSPredicate predicateWithFormat:@“testID >= %@ AND testID <=%@”, @1ll, @13ll];
三、过滤数组、Set
0、过滤方法
过滤 NSArray:filteredArrayUsingPredicate:
使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的 新集合
NSMutableArray:filterUsingPredicate:
使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素
NSSet filteredSetUsingPredicate:
NSMutableSet filterUsingPredicate:
通过上面的描述可以看出,使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,没有返回值,会直接剔除不符合条件的集合元素
1、数值数组筛选
数值数组,筛选数值在某个范围内
NSArray *testArray = @[@1, @2, @3, @4, @5, @6];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];
NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"filterArray:%@", filterArray);//3,4
2、字符串数组的筛选
常用的一般根据包含内容、字符串长度进行筛选
其他功能可参考上面对字符串进行判断的方法
- (void)testPre1{
NSArray *testArray = @[@"JOLLY",@"billy", @"John", @"Joe", @"Tiffany", @"Mary", @"David"];
//筛选字符长度大于4的元素
NSPredicate *pre0 = [NSPredicate predicateWithFormat:@"SELF.length > 4"];
NSArray *filterArray0 = [testArray filteredArrayUsingPredicate:pre0];
NSLog(@"filterArray0:%@", filterArray0);//billy,Tiffany,David
//取出包含‘Jo’的元素
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'Jo'"];
NSArray *filterArray1 = [testArray filteredArrayUsingPredicate:pre1];
NSLog(@"filterArray1:%@", filterArray1);//John,Joe
NSString *keyword = @"Jo";
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF.lowercaseString CONTAINS '%@'",keyword.lowercaseString];
NSArray *filterArray2 = [testArray filteredArrayUsingPredicate:pre2];
NSLog(@"filterArray2:%@", filterArray2);//JOLLY,John,Joe
}
3、取两个数组的交集
使用 集合运算符中的 IN
运算符
NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
NSArray *subArray = @[@"ab", @"abc",@"ab1"];
NSPredicate *pre0 = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", subArray];//不包含在subArray的元素
NSLog(@"0-%@", [array filteredArrayUsingPredicate:pre0]);//a,abcd
NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"SELF IN %@", subArray];//包含在subArray的元素
NSLog(@"1-%@", [array filteredArrayUsingPredicate:pre1]);//ab,abc
4、过滤模型数组
这里创建一个模型 PersonModel 方便解释下面使用,PersonModel 包含属性:
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *sex;
@property (nonatomic,assign) NSInteger age;
-(instancetype)initWithName:(NSString *)name sex:(NSString *)sex age:(NSInteger)age;
创建测试数据:
PersonModel *model0 = [[PersonModel alloc]initWithName:@"joe" sex:@"female" age:18];
PersonModel *model1 = [[PersonModel alloc]initWithName:@"jim" sex:@"female" age:20];
PersonModel *model2 = [[PersonModel alloc]initWithName:@"jone" sex:@"female" age:23];
PersonModel *model3 = [[PersonModel alloc]initWithName:@"milly" sex:@"female" age:25];
PersonModel *model4 = [[PersonModel alloc]initWithName:@"Elaine" sex:@"female" age:28];
NSArray *array = @[model0,model1,model2,model3,model4];
筛选名字包含 jo 的模型, 下面四种方式搜索结果相同:
NSPredicate *pred0 = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", @"name", @"jo"];
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"name CONTAINS %@", @"jo"];
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS %@", @"jo"];
NSPredicate *predTemp3 = [NSPredicate predicateWithFormat:@"%K CONTAINS $VALUE", @"name"];
NSPredicate* pred3 = [predTemp3 predicateWithSubstitutionVariables:@{@"VALUE" : @"jo"}];
NSLog(@"%@", [array filteredArrayUsingPredicate:pred0]);
NSLog(@"%@", [array filteredArrayUsingPredicate:pred1]);
NSLog(@"%@", [array filteredArrayUsingPredicate:pred2]);
NSLog(@"%@", [array filteredArrayUsingPredicate:pred3]);
其中
- 属性作为key,可以用
%K
表示。 - 使用 $ 修饰的字符,可以作为参数,在
predicateWithSubstitutionVariables
中使用字典的形式赋值;在其他时候赋值,也方便产生多个条件类似的过滤器。Value 字符也可以替换为其他字符,只要前后统一即可,最好不要用关键字。
下面示例同样使用到这个方法,方便你的理解:
predicateWithSubstitutionVariables
// 创建谓词,属性名改为age,要求这个age包含$VALUE字符串
NSPredicate *predTemp4 = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];
// 指定$VALUE的值为 20
NSPredicate *pred4 = [predTemp4 predicateWithSubstitutionVariables:@{@"VALUE" : @20}];
NSLog(@"%@", [array filteredArrayUsingPredicate:pred4]);//筛选到年级大于20的模型