NSPredicate谓词的用法 数组过滤

转自:http://blog.csdn.net/daiyelang/article/details/18546405


NSPredicate 用于指定过滤条件,主要用于从集合中分拣出符合条件的对象,也可以用于字符串的正则匹配。
NSPredicate常用方法介绍
self 就是数组中添加的东西, 可以是model, 也可以是字符串, such as : self.age<20 和 age<20是一样的, (必须数组中的对象含有一个age的属性)
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 1.创建NSPredicate(相当于创建一个过滤条件)  
  2. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"过滤条件"];  
  3. 2.判断指定的对象是否满足NSPredicate创建的过滤条件  
  4. [predicate evaluateWithObject:person];  
  5. 3.过滤出符合条件的对象(返回所有符合条件的对象)  
  6. NSArray *persons = [array filteredArrayUsingPredicate:predicate];  

实例:(以下为伪代码,只为讲解问题)
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 1.先创建一个person对象  
  2. @interface Person: NSObject{  
  3. NSString *name;  
  4. int age;  
  5. }  
  6.   
  7. 2.创建一个数组,在数组种加入多个person对象  
  8. NSArray *array=[NSArray arrayWithObjects:person1,person2,person3,person4,...,nil];  
  9.   
  10. 3.使用NSPredicate来过滤array种的person  
  11. a.找出array种age小于20的person  
  12. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 20"];  
  13. for(Person *person in array){  
  14.     if([predicate evaluateWithObject:person]){ //判断指定的对象是否满足  
  15.         //........................  
  16.     }  
  17. }  
  18. NSArray *persons = [array filteredArrayUsingPredicate:predicate];//获取所有age小于20的person  


使用方法主要就这几步,以下讲一些常用的NSpredicate的条件
1.逻辑运算符号 > , < , = , >= , <= 都能使用在这里

运算符还可以跟逻辑运算符一起使用,&&  ,  || ,AND, OR 谓词不区分大小写
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age > 20"];  
  2. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name > 'abc' && age > 10"];  
  3. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name > 'abc' OR age > 10"];  
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <span style="font-family: Arial, Helvetica, sans-serif;"></span><p class="p1">  
  2. </p>  

2.IN

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN {'abc' , 'def' , '123'}"];  

3.以xx开头,  以xx结尾 --beginswith endswitch

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'N'"];//name以N打头的person  
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. </pre>4.以xx结尾--endswith</div><div></div><div><pre code_snippet_id="163702" snippet_file_name="blog_20140120_8_9862346" name="code" class="objc">NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name ENDSWITH 'N'"];//name以N结尾的person  

5.包含 -- contains

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS 'N'"]; <span style="font-family: Arial, Helvetica, sans-serif;">//name种包含'N的person</span>  

6.模糊查询--like
*a : 以a结尾的
*a* : 字符串含有a字符串的
?a* : 第二个字符串为a的
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name LIKE '*N*'"];//<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14.44444465637207px; line-height: 26px;">*表示零个或多个字符</span>  

7.以上说的都是对象种的属性匹配,如果数组种都是字符串如何匹配--self
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSArray *array=[NSArray arrayWithObjects@"abc"@"def"@"ghi",@"jkl", nil nil];  
  2. NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF=='abc'"];  
  3. NSArray *array2 = [array filteredArrayUsingPredicate:pre];  

 8.正则表达式
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. (8.) 正则表达式:  
  2. NSPredicate 使用MATCHES 匹配正则表达式,正则表达式的写法采用international components  
  3. for Unicode (ICU)的正则语法。  
  4. 例:  
  5. NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。  
  6. NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];  
  7. if([pre evaluateWithObject@"Apple"]){  
  8. printf("YES\n");  
  9. }else{  
  10. printf("NO\n");  
  11. }  


转自:http://loxe.me/archives/7/


NSPredicate是什么

NSPredicate:谓词
字面翻译是这个意思,但是我觉得谓词这个词太难以理解了
NSPredicate的具体用途应该还是过滤,类似于过滤条件之类的,相当于一个主语的谓语,所以说会是谓词这个名字。(我是这么理解的)

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的筛选

  1. 没有使用NSPredicate的筛选应该大家都会写,循环+判断。。。
  2. 使用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的其他说明和注意事项,以及技巧

  1. 动态属性名

假如你的代码如下

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 的简单的使用就介绍到这里,这里有些都是从网络上其他人的额博客转过来的内容,我自己加以修改和一些自己的理解。希望可以帮到大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值