Predicates
Predicates provide a general means of specifying queries in Cocoa. The predicate system is capable of handling a large number of domains, including Core Data and Spotlight.
苹果官方的描述Predicates是在Cocoa中的一种查询格式,可以用于大量数据时候的查询操作,包含Core Data和 Spotlight中;
通过我们过滤数据的方式是通过一个循环,在循环中建立过滤条件,然后对过滤的数据进行操作,或者增加到一个新的容器当中,例如新建一个Array; 在iOS中有一种更加优雅的方式来实现,通过Predicate,建立一个模式,然后对数据进行模式匹配,筛选出符合条件的数据。
demo地址:下载
过滤中间数据
- (void)predicateWithBetween {
//1
NSPredicate *betweenPredicate = [NSPredicate predicateWithFormat:@"attributeName BETWEEN %@",@[@1,@10]];
NSDictionary *dictionary = @{@"attributeName":@5};
// 2
BOOL between = [betweenPredicate evaluateWithObject:dictionary];
if (between) {
NSLog(@"between");
}
}
1.建立正则表达式,表示数据的范围是[1-10],并且定义一个字典
2.对该字典执行Predicate匹配,between用来接收匹配的结果
匹配数组中的数据
- (void)evaluationAPredicate {
// 1
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@",@[@"Stig",@"Shaffiq",@"Chris"]];
BOOL result = [predicate evaluateWithObject:@"Shaffiq"];
// 2
// object must support key-value coding
if (result) {
NSLog(@"evaluate predicate success");
}
}
1.建立predicate,筛选出是否包含该字符串集合;
2.对字符串进行匹配,要求匹配对象必须满足kvc;
过滤数据中的数据
- (void)predicateWithArrays {
NSMutableArray *names = [@[@"Nick",@"Ben",@"Adam",@"Melissa"] mutableCopy];
// 1
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB = [names filteredArrayUsingPredicate:bPredicate];
NSLog(@"beginWithB:%@",beginWithB);
// 2
NSPredicate *ePredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] 'e'"];
NSArray *containsE = [names filteredArrayUsingPredicate:ePredicate];
NSLog(@"contains e:%@",containsE);
}
1.过滤数组中以 “b” 开头的字符;
2.过滤数组中包含“e”的字符串
过滤数组中的空数据
- (void)predicateWithNullValue {
NSString *firstName = @"Ben";
// NSArray *array = @[@{@"lastName":@"Turner"}];
// @{@"firstName":@"Ben",@"lastName":@"Ballard",@"birthday":[NSDate dateWithString:@"1972-03-24 10:45:32 +0600"]};
NSArray *array = @[ @{@"lastName":@"Turner"},
@{ @"firstName" : @"Ben",
@"lastName" : @"Ballard",
@"birthday" : [NSDate dateWithString:@"1972-03-24 10:45:32 +0600"] } ];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName like %@",firstName];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filtered Array:%@",filteredArray);
// using greater than method
NSDate *referenceDate = [NSDate dateWithTimeIntervalSince1970:0];
// 1
predicate = [NSPredicate predicateWithFormat:@"birthday > %@",referenceDate];
filteredArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filtered2 Array:%@",filteredArray);
// test for null value
// 2
predicate = [NSPredicate predicateWithFormat:@"(firstName == %@) || (firstName = nil)",firstName];
filteredArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"filtered3 Array:%@",filteredArray);
// test null result ok
// 3
predicate = [NSPredicate predicateWithFormat:@"firstName = nil"];
BOOL ok = [predicate evaluateWithObject:[NSDictionary dictionary]];
// 打印的格式控制符号https://blog.youkuaiyun.com/liangliang2727/article/details/40652557
NSLog(@"ok 1:%hhd",ok);
// 4
ok = [predicate evaluateWithObject:[NSDictionary dictionaryWithObject:[NSNull null] forKey:@"firstName"]];
NSLog(@"ok 2:%hhd",ok);
}
- 过滤birthday在referenceDate之后的日期的数据;
- 过滤数组中firstName为空的数据;
- 过滤空字典中键值firstName为空的数据;
- 过滤字典中firstName对应的Value为[NSNull null]的数据
通过正则表达式过滤
- (void)predicateWithRegularExpressions {
NSArray *array = @[@"TATACCATGGGCCATCATCATCATCATCATCATCATCATCATCACAG",
@"CGGGATCCCTATCAAGGCACCTCTTCG", @"CATGCCATGGATACCAACGAGTCCGAAC",
@"CAT", @"CATCATCATGTCT", @"DOG"];
//'.*(CAT){3,}(?!CA).*'
NSPredicate *catPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '.*(CAT){3,}(?!CA).*'"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:catPredicate];
NSLog(@"filetered Array :%@",filteredArray);
// ICU的正则表达方式
NSArray *isbnTestArray = @[@"123456789X", @"987654321x", @"1234567890", @"12345X", @"1234567890X"];
NSPredicate *isbnPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '\\\\d{10}|\\\\d{9}[Xx]'"];
NSArray *isbnArray = [isbnTestArray filteredArrayUsingPredicate:isbnPredicate];
NSLog(@"filetered Array :%@",isbnArray);
}
特殊字符组:如匹配任意字母字符,匹配任意字母数字字符,空格或者制表符,0-9,a-z, 任意可打印的字符,标答符号,大写的A-Z;
| 字符 | 名称 | 描述 |
|---|---|---|
| ^(BRE) | 脱字符 | 表示在行首页 |
| $ | 美元符 | 定义行尾锚点 |
| . | 点 | 匹配任意单个字符 |
| [] | 定义一个字符组 | [ch],其中的字符c和h是或的逻辑,c或者h |
| [^] | 字符组取反 | 表示过滤字符组中没有的字符 |
| [0-9] | -用来表示数据区间 | 区间也适用于字母如[a-z]; 也可以表示不连续的区间[a-ch-m]; |
| * | 一次或者多次 | a*,符号后面放*表示该符号出现一次或者多次; |
| ?(ERE) | 问号 | 类似于*,b[ae]?t -> bt, 匹配前面的字符出现0次或者一次; |
| + | 加号 | 类似于*,匹配一次或者多次,至少出现一次; |
| {m,n} | m,n表示为出现的次数 | 至少出现m次,最多出现n次; |
| | | 逻辑或 | 处理两种匹配模式 |
| () | 括号 | 正则表达式的分组 |
参看资料:
- 正则表达式的处理,《linux 命令行与shell脚本编程大全》 428 页, 20章
- Apple Predicate官方文档
本文介绍了在Cocoa中如何利用Predicates进行高效的数据查询与过滤。包括基本的查询格式设置,通过Predicate进行数据筛选的方法,并提供了多个示例,如过滤特定范围的数据、匹配数组中的元素、处理空值及使用正则表达式等。
964

被折叠的 条评论
为什么被折叠?



