系统提供了NSPredicate这个类给我们进行一些匹配、筛选操作,非常方便。在没有用这个类时,我们要获取两个数组中某些特定的元素时,需要写代码一一对比,但是使用了这个类,只需要三四行代码就够了。
先演示一个谓词在在类中使用
KKMonthModel.h文件
@interface KKMonthModel : KKBaseModel
/**年份*/
@property(nonatomic,copy)NSString *date_year;
/**月份*/
@property(nonatomic,copy)NSString *date_month;
/**日*/
@property(nonatomic,copy)NSString *date_day;
/**预约数量*/
@property(nonatomic,copy)NSString *appoint_num;
/**上门数量*/
@property(nonatomic,copy)NSString *receive_num;
@end
KKMonthModle.m文件(取开发中的部分代码示例)
if (models.count>0) {
for (KKMonthModel *monthModel in models) {
NSPredicate *pre=[NSPredicate predicateWithFormat:@"year==%ld&& month==%ld&& day==%ld",monthModel.date_year.integerValue,monthModel.date_month.integerValue,monthModel.date_day.integerValue];
NSArray *preArray=[headerModel.calendarItemArray filteredArrayUsingPredicate:pre];
if (preArray.count>0) {
KKCalendarModel *model=[preArray lastObject];
model.monthModel=monthModel;
}
}
谓词主要实现对数组的筛选,数组里面可是字典,当然也可以是数组。下面让我给大家讲讲谓词中常见的使用方法和场景
谓词的使用使用方法
(1)比较运算符
/**比较运算符
* >:大于
* <:小于
* >=:大于等于
* <=:小于等于
* =,==:等于
* !=,<>:不等于
* BEGINSWITH:检查某个字符串是否以指定的字符串开头(如判断字符串是否以a开头:BEGINSWITH 'a')
* ENDSWITH:检查某个字符串是否以指定的字符串结尾
* CONTAINS:检查某个字符串是否包含指定的字符串
* LIKE:检查某个字符串是否匹配指定的字符串模板。其之后可以跟?代表一个字符和*代表任意多个字符两个通配符。比如"name LIKE '*ac*'",这表示name的值中包含ac则返回YES;"name LIKE '?ac*'",表示name的第2、3个字符为ac时返回YES。
*MATCHES:检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。
// 例子:年龄属性大于3岁,注意:键路径不能用单引号引起来,否则会报错
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 3"];
(2)逻辑运算符
/**逻辑运算符
* and/&&:与
* or/||:或
* not/!:非
**/
// 例子:年龄大于三岁或名字叫“zhang1”的,注意:字符串的值需要用单引号引起来,否则会报错,错误信息是:this class is not key value coding-compliant for the key zhang1.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 3 || name = 'zhang1'"];
(3)关系运算符
/**关系操作
* 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' }。
**/
// 例子:in关键字:左边的关键字里必须包含右边的集合的元素
NSPredicate *predicate = [NSPredicate predicateWithFormat:@" name in {'zhang1','zhang4'}"];
谓词的使用场景
(1)谓词对对象数组的操作
#import <Foundation/Foundation.h>
@interface Products : NSObject
@property NSString *productName;
@property NSInteger productCount;
@property NSString *productImageUrl;
+(id)initProductWithName:(NSString *) name withCount:(NSInteger) count withImage:(NSString *) imageurl;
@end
.m文件中的使用
#import "ViewController.h"
#import "Products.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self mainTest];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void) mainTest
{
Products *p1=[Products initProductWithName:@"A苹果sdasf" withCount:2 withImage:@"464.jpg"];
Products *p2=[Products initProductWithName:@"fsdf橘子gag" withCount:53 withImage:@"fsdfas.jpg"];
Products *p3=[Products initProductWithName:@"dfgdf香蕉" withCount:5 withImage:@"sfas.jpg"];
Products *p4=[Products initProductWithName:@"三星" withCount:76 withImage:@"ggas.jpg"];
Products *p5=[Products initProductWithName:@"华为dfsd" withCount:9 withImage:@"gasa.jpg"];
Products *p6=[Products initProductWithName:@"微软dhnnne" withCount:6 withImage:@"hshhh.jpg"];
Products *p7=[Products initProductWithName:@"三星" withCount:6 withImage:@"hshhh.jpg"];
Products *p8=[Products initProductWithName:@"15300250500" withCount:6 withImage:@"hshhh.jpg"];
NSArray *sproducts=[NSArray arrayWithObjects:p1,p2,p3,p4,p5,p6,p7,nil];
//数量小于9 定义谓词 包含过滤条件
NSPredicate *prdicate=[NSPredicate predicateWithFormat:@"productCount<%d",9];
//过滤结果返回新的数组
NSArray *newArray=[sproducts filteredArrayUsingPredicate:prdicate];
for (Products *item in newArray) {
NSLog(@"newArray=%@",item.productName);
}
//数量大于9 并且productname等于“三星jfggg” 定义谓词 包含过滤条件
prdicate=[NSPredicate predicateWithFormat:@"productName='三星' && productCount>9"];
//过滤结果返回新的数组
newArray=[sproducts filteredArrayUsingPredicate:prdicate];
for (Products *item in newArray) {
NSLog(@"newArray=%@",item.productName);
}
//in(包含) *注意 包含是全字匹配
prdicate = [NSPredicate predicateWithFormat:@"productName IN {'g','华为','三星'}||productCount IN {2,5}"];
//过滤结果返回新的数组
newArray=[sproducts filteredArrayUsingPredicate:prdicate];
for (Products *item in newArray) {
NSLog(@"newArray=%@",item.productName);
}
//productName以a开头的
prdicate = [NSPredicate predicateWithFormat:@"productName BEGINSWITH 'A'"];
//productName以ba结尾的
prdicate = [NSPredicate predicateWithFormat:@"productName ENDSWITH 'g'"];
//name中包含字符a的
prdicate = [NSPredicate predicateWithFormat:@"productName CONTAINS 'a'"];
//like 匹配任意多个字符
//productName中只要有s字符就满足条件
prdicate = [NSPredicate predicateWithFormat:@"productName like '*s*'"];
//?代表一个字符,下面的查询条件是:name中第二个字符是s的
prdicate = [NSPredicate predicateWithFormat:@"productName like '?s*'"];
newArray=[sproducts filteredArrayUsingPredicate:prdicate];
for (Products *item in newArray) {
NSLog(@"newArray=%@",item.productName);
}
//正则表达式 验证是否是手机号
BOOL isMobileNum=[self isMobileNumber:p8.productName];
if(isMobileNum)
NSLog(@"是真确的手机号:%@",p8.productName);
}
- (BOOL)isMobileNumber:(NSString *)mobileNum
{
/**
* 手机号码
* 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
* 联通:130,131,132,152,155,156,185,186
* 电信:133,1349,153,180,189
*/
NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
/**
10 * 中国移动:China Mobile
11 * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
12 */
NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
/**
15 * 中国联通:China Unicom
16 * 130,131,132,152,155,156,185,186
17 */
NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
/**
20 * 中国电信:China Telecom
21 * 133,1349,153,180,189
22 */
NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
/**
25 * 大陆地区固话及小灵通
26 * 区号:010,020,021,022,023,024,025,027,028,029
27 * 号码:七位或八位
28 */
// NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
if (([regextestmobile evaluateWithObject:mobileNum] == YES)
|| ([regextestcm evaluateWithObject:mobileNum] == YES)
|| ([regextestct evaluateWithObject:mobileNum] == YES)
|| ([regextestcu evaluateWithObject:mobileNum] == YES))
{
if([regextestcm evaluateWithObject:mobileNum] == YES) {
NSLog(@"中国移动");
} else if([regextestct evaluateWithObject:mobileNum] == YES) {
NSLog(@"联通");
} else if ([regextestcu evaluateWithObject:mobileNum] == YES) {
NSLog(@"电信");
} else {
NSLog(@"Unknow");
}
return YES;
}
else
{
return NO;
}
}
@end
(2)谓词对字典数组的操作
dataArray = [[NSMutableArray alloc] init];
NSDictionary * dataDic1 = @{@"image":[UIImage imageNamed:@"photo1.jpg"], @"content":@"I am a boy",@"publisher":@"趣玩高球", @"privateNum":@"122",@"lookNum":@"56"};
NSDictionary * dataDic2 = @{@"image":[UIImage imageNamed:@"photo2.jpg"], @"content":@"昨天中午有个男同事外出,没把手机带走。他老婆不停地打电话来。午睡的女同事被吵烦了,拿过手机大吼:我们在睡觉,你烦不烦!结果,那位男同事今天到现在都没来上班!",@"publisher":@"趣玩高球", @"privateNum":@"122",@"lookNum":@"56"};
NSDictionary * dataDic3 = @{@"image":[UIImage imageNamed:@"photo3.jpg"], @"content":@"yesterday,my mom buy a apple!",@"publisher":@"趣玩高球", @"privateNum":@"122",@"lookNum":@"56"};
NSDictionary * dataDic4 = @{@"image":[UIImage imageNamed:@"photo4.jpg"], @"content":@"昨天中午有个男同事外出,没把手机带走。他老婆不停地打电话来。午睡的女同事被吵烦了,拿过手机大吼:我们在睡觉,你烦不烦!结果,那位男同事今天到现在都没来上班!",@"publisher":@"趣玩高球", @"privateNum":@"122",@"lookNum":@"56"};
[dataArray addObject:dataDic1];
[dataArray addObject:dataDic2];
[dataArray addObject:dataDic3];
[dataArray addObject:dataDic4];
这里是过滤KEY为@“content”的值为输入框的值来搜索包含有这个输入框输入的文字的字典。
NSString * searchString = [lifeSearchController.searchBar text];
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS[c] %@",@"content",searchString];
if (searchListArray != nil) {
[searchListArray removeAllObjects];
}
//过滤数据
searchListArray = [NSMutableArray arrayWithArray:[dataArray filteredArrayUsingPredicate:predicate]];
NSLog(@"return****** %@",searchListArray);
//刷新表格
[headTableView reloadData];