谓词(NSPredicate)
OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据。非常方便。在Java中是没有这种技术的,但是有开源的框架已经实现了此功能。
下面看具体的例子。
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
+(id)personWithName:(NSString *)name andAge:(NSInteger)age;
@end
Person.m
#import "Person.h"
@implementation Person
+(id)personWithName:(NSString *)name andAge:(NSInteger)age
{
Person *person = [[Person alloc]init];
person.name = name;
person.age = age;
return person;
}
-(NSString *)description
{
NSString *s = [NSString stringWithFormat:@"name=%@,age=%ld", _name, _age];
return s;
}
@end
下面看一下简单的用法
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property (nonatomic, strong) NSArray *persons;
@end
@implementation ViewController
- (NSArray *)persons
{
if (_persons == nil) {
self.persons = [NSArray arrayWithObjects:
[Person personWithName:@"mac" andAge:20],
[Person personWithName:@"1" andAge:30],
[Person personWithName:@"2" andAge:40],
[Person personWithName:@"3" andAge:50],
[Person personWithName:@"4" andAge:60],
[Person personWithName:@"5" andAge:70],
[Person personWithName:@"6" andAge:20],
[Person personWithName:@"7" andAge:40],
[Person personWithName:@"8" andAge:60],
[Person personWithName:@"9" andAge:40],
[Person personWithName:@"我" andAge:80],
[Person personWithName:@"10" andAge:90],
[Person personWithName:@"1" andAge:20], nil];
}
return _persons;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < %d", 30];
// 查询name=1的并且age大于40
predicate = [NSPredicate predicateWithFormat:@"name = '1' && age < %d", 40];
// in 包含
predicate = [NSPredicate predicateWithFormat:@"self.name IN {'1','2','4'} || self.age IN {30,40}"];
// name 以m开头
predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'm'"];
// name 以c结尾
predicate = [NSPredicate predicateWithFormat:@"name ENDSWITH 'a'"];
// name 包含
predicate = [NSPredicate predicateWithFormat:@"name CONTAINS '我'"];
// like 匹配任意多个字符
// name中只要有s字符就能满足条件
predicate = [NSPredicate predicateWithFormat:@"name like '*我*'"];
// ? 代表一个字符,*代表任意多个字符。下面的查询条件是:name中第二个字符是a,name有2个字符
predicate = [NSPredicate predicateWithFormat:@"name like '?a'"];
// name中第二个字符是a, name有任意多个字符
predicate = [NSPredicate predicateWithFormat:@"name like '?a'"];
NSArray *array = [self.persons filteredArrayUsingPredicate:predicate];
NSLog(@"filterArray=%@", array);
}
@end
NSPredicate 中的运算符
从上面的例子中我们看到,创建谓词使用类方法predicateWithFormat: (NSString*) format,format 里的东西真的和SQL 的where 条件类似。另外,参数format 与NSLog 的格式化模版类似。另外谓词可以配合正则使用,功能强大。
-
比较运算符 > 、< 、== 、 >= 、<= 、 !=
-
逻辑运算符:AND、OR、NOT 这几个运算符计算并、或、非的结果。
-
范围运算符:IN 、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}" -
字符串本身:SELF
例:@"SELF == 'APPLE'" -
字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
例: @"name CONTAINS[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以某个字符串开头
@"name ENDSWITH[d] 'ang'" //以某个字符串结束
注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。 -
通配符:LIKE
例:@"name LIKE[cd] 'er'" //代表通配符,Like也接受[cd].
@"name LIKE[cd] '???er'" -
正则表达式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A开头,e结尾
@"name MATCHES %@",regex
使用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"}
使用正则筛选一个数组
NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Apple"]){
printf("YES\n");
}else{
printf("NO\n");
}
网友评论