NSPredicate:谓词
字面翻译是这个意思,但是我觉得谓词这个词太难以理解了NSPredicate
的具体用途应该还是过滤,类似于过滤条件之类的,相当于一个主语的谓语,所以说会是谓词这个名字。(我是这么理解的)
原文在这里(http://blog.csdn.net/lmf208/article/details/38345321)
NSPredicate
的创建
我们看到创建谓词使用类方法
predicateWithFormat: (NSString *)format
format
里的东西真的和SQL
的where
条件差不多。另外,参数format
与NSLog
的格式化模版差不多,如果 1 和
188.0 是传递过来的参数,你可以写成如下的形式:
@"pid>%d and height<%f",1,188.0
NSPredicate
中主要的几种运算方式
1.比较运算符
> 、< 、== 、 >= 、<= 、 !=
例:@"number >= 99"
2.逻辑运算符:
AND
、OR
、NOT
这几个运算符计算并、或、非的结果。3.范围运算符:
IN
、BETWEEN
例:
@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}"
- 4.字符串本身:SELF 例:
@"SELF == 'APPLE'"
- 5.字符串相关:
BEGINSWITH
、ENDSWITH
、CONTAINS
例:
@"name CONTAIN[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以某个字符串开头
@"name ENDSWITH[d] 'ang'" //以某个字符串结束
注:`[c]`不区分大小写 , `[d]`不区分发音符号即没有重音符号 , `[cd]`既不区分大小写,也不区分发音符号。
- 6.通配符:LIKE
例:
@"name LIKE[cd] '*er*'"
// * 代表通配符,Like也接[cd].
@"name LIKE[cd] '???er*'"`
- 7.正则表达式:
MATCHES
例:
NSString *regex = @"^A.+e$";
//以A开头,e结尾
@"name MATCHES %@",regex
如何使用NSPredicate
对一个自定义实体进行筛选NSPredicate
我暂时都是用于过滤的,否则我们过滤就需要自己写判断 写循环,去判断输出了。
接下来就上代码和例子吧。
建立一个实体类
Dog
@property (copy , nonatomic) NSString* name;
@property (assign , nonatomic) int age ;
//这样我们就有一个类了
//我们创建 5只Dog的实体
Dog * dog1=[Dog news];
dog1.name=@"这是第一只Dog";dog1.age=@"11";
Dog * dog2=[Dog news];
dog2.name=@"这是第二只Dog";
dog2.age=@"22";
Dog * dog3=[Dog news];
dog3.name=@"这是第三只Dog";
dog3.age=@"33";
Dog * dog4=[Dog news];
dog4.name=@"这是第四只Dog";
dog4.age=@"44";
Dog * dog5=[Dog news];
dog5.name=@"这是第五只Dog";
dog5.age=@"55";
不要吐槽我的Dogs的年龄 → 。→
然后我们需要一个Array把他们都装进去
NSArray * dogArr=@[dog1,dog2,dog3,dog4,dog5];
酱紫所有的Dog都装到一个数组里了使用NSPredicate
的筛选没有使用NSPredicate
的筛选应该大家都会写,循环+判断。。。
使用NSPredicate
的筛选具体使用的代码
//创建谓词的对象 谓词条件是基于KVC的,所以需要说明一点,加入Dog里面有个属性是Doginfo指向Doginfo类,
//在使用的时候 我们的条件就要写成Doginfo.xxx了。
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name=='这是第一只Dog' AND age ==11"];
for(Dog * d in dogArr)
{
if([predicate evaluateWithObject:d])
{
NSLog(d.name);
}
}
以上的代码打印出来的结果就是 这是第一只Dog
NSPredicate
筛选一个对象逻辑还是很清晰的,不过这里比较麻烦的就是 还有一个循环,这里我们会发现数组提供了一个方法可以更方便的检索数组对象
直接筛选出一个符合谓词的新数组。
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age >11"];
NSMutableArray *arrayPre=[dogArr filteredArrayUsingPredicate: pre];
arrayPre
里面的对象就会是 除了dog1之外的所有的dog。(至于为什么看我的条件…)
看到这里发现NSPredicate 可以用于自定义的实体的检索、筛选,那如果用于 NSString
,NSInteger
,bool
呢?那我们再看一段代码吧
NSArray *arrays=[NSArray arrayWithObjects: @"Apple", @"Google", @"MircoSoft", nil];
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF=='Apple'"];
上面这段代码是匹配字符串的时候 NSPredicate 需要如何声明
使用NSPredicate在两个数组之间进行差异筛选
NSArray* array = @[@"aa",@"bb"];
NSArray* array2 = @[@"aa",@"bb",@"cc",@"dd"];
NSPredicate* thePredicate = [NSPredicate predicateWithFormat:@"NOT(SELF in %@)",array];
NSArray* arr3 = [array2 filteredArrayUsingPredicate:thePredicate];
NSLog(@"%@",arr3);
上面的代码输出结果
arr3={@"cc" ,@"dd"}
这样大家就很容易理解了
SELF在前面有介绍过 可以往回翻阅一下
如何使用正则筛选一个数组
NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Apple"]){
printf("YES\n");
}else{
printf("NO\n");
}
关于NSPredicate
的其他说明和注意事项,以及技巧
动态属性名
假如你的代码如下
NSPredicate *p = [NSPredicate predicateWithFormat:@"name = %@", @"name1"];
显然代码没有任何问题,但是这个不是最好的写法, 我建议如下写法:
NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@"name1", @"NAME",nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
这样看上去可能会让代码逻辑更清晰。
当过滤条件字段都是动态的时候
NSString *key = @"name";
NSString *value = @"name1";
NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ = %@", key, value];
然后当你执行到第三行的时候代码就会报错!
逻辑上没错误啊!!!为什么会出错呢?NSPredicate
要自动添加引号,所以最后得到的格式应该是
@"'name' = 'name1'"。
明显不对。要做的就是:
NSPredicate *p = [NSPredicate predicateWithFormat:@"%K = %@", key, value];
总结NSPredicate
的简单的使用就介绍到这里,这里有些都是从网络上其他人的额博客转过来的内容,我自己加以修改和一些自己的理解。希望可以帮到大家。
本文地址: http://yongqianvip.github.io/2015/11/05/aboutNSPredicate/