- 什么要使用谓词?
使用谓词可以方便地实现:根据某个条件进行查询、修改、删除等操作。
Core Data中需要使用谓词,进行数据库的操作 - 谓词的创建
创建谓词时,需要使用“键”或者“键路径”
2.1 直接创建谓词
谓词中的条件是“硬编码”。
字符串值,需要使用单引号扩起来。
接口 | +(NSPredicate*)predicateWithFormat:(NSString*)predicateFormat,… |
---|---|
实例 |
NSPredicate * predicate = [NSpreadicate predicateWithFormat:@"make =='BMW'"];//mark是KVC中的键
predicate = [NSPredicate predicatWithFormat:@"engine.horsepower >70"];//engine.horsepower 是KVC 中的键路径
2.2 使用格式说明符创建谓词
谓词中使用“硬编码”,不灵活
1 使用%d等
predicate = [NSpredicate PredicateWithFormat:@"engine.horsepower> %d",70];
2 使用%@ 等
NSString* name = @"BMW";
NSpredicate * predicate = [NSpredicate predicateWithFormat:@"mark == %@",name];
3 使用%K(表示键或键路径)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@",
@"mark", @"BMW"];
4 使用“变量名”
//1. 定义一个谓词模板,该谓词模板中使用了“变量”
NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"mark == $Name"];
//2. 定义一个变量字典
//“变量”是字典中的键,键都是字符串形式。
NSDictionary *vars = @{@"Name":@"BMW", @"Power":@70};
//3. 谓词模板使用变量字典,返回一个真正的谓词
//等效于:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"mark == 'BMW'"];
NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables:vars];
总结:只能使用%K表示键、键路径,$变量只能表示值
3 谓词的使用
3.1 直接使用谓词
谓词的实例方法
- (BOOL)evaluateWithObject:(id)object;
if ([predicate evaluateWithObject:car]) {
NSLog(@"匹配");
} else {
NSLog(@"不匹配");
}
3.2 数组使用谓词进行过滤
1 数组使用谓词进行过滤,返回过滤后的数组
数组的实例方法
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;
NSArray *strs = @[@"Hello", @"Hi", @"world", @"12345678"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"length >= 5"];
NSArray *ret = [strs filteredArrayUsingPredicate:predicate];
NSLog(@"%@", ret);
2 数组使用谓词进行过滤,删除不匹配的元素。
可变数组的实例方法
- (void)filterUsingPredicate:(NSPredicate *)predicate;
NSMutableArray *strs = [NSMutableArray arrayWithObjects:
@"Hello", @"Hi", @"world", @"12345678", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"length >= 5"];
[strs filterUsingPredicate:predicate];
NSLog(@"%@", strs);
补充. 数据使用KVC,返回一个新的数组。
数组的实例方法
- (id)valueForKey:(NSString *)key;
NSMutableArray *strs = [NSMutableArray arrayWithObjects:
@"Hello", @"Hi", @"world", @"12345678", nil];
//获取的值如果不是oc对象,将被自动装箱
NSArray *ret = [strs valueForKey:@"length"];
NSLog(@"%@", ret);
4.2 数组运算符
1)数据运算符符BETWEEN,确定区间
注意, BETWEEN不区分大小写, 区间是“开区间”(不包括端点)。
方式1:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"engine.horsepower BETWEEN {50, 80}"];
等效于:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"(engine.horsepower > 50) && (engine.horsepower < 80)"];
方式2:
int low = 50;
int high = 80;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"engine.horsepower BETWEEN {%d, %d}", low, high];
方式3:
NSArray *betweens = @[[NSNumber numberWithInt:50], [NSNumber numberWithInt:80]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"engine.horsepower BETWEEN %@", betweens];
2)数组运算符IN, 是否包含
IN不区分大小写。
方式1:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"mark IN {'BMW', 'Jeep', 'ISUZU'}"];
方式2:
NSArray *marks = @[@"BMW", @"Jeep", @"ISUZU"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"mark IN %@", marks];
4.3 SELF
为什么要使用SELF?
问题:
NSArray *marks = @[@"BMW", @"Jeep", @"ISUZU"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"mark IN %@", marks];
NSArray *result = [cars filteredArrayUsingPredicate:predicate];
实际上是对数组cars的每个元素(car对象),获取mark键对应的值。
即谓词中使用了键或者键路径.
那么问题来了:
如果被计算的数组cars存放的不是car对象,而是字符串,
那么在使用mark键值就不合适了。
解决方案:使用SELF
什么是SELF?
SELF表示谓词计算的对象本身,
比如,对数组使用filteredArrayUsingPredicate进行谓词计算时,
则实际上是对数组中的每一个元素分别进行计算。
此时,SELF就表示数组中的元素本身。
实例:
NSArray *ChinaMarks = @[@"北京", @"吉利", @"BYD", @"长城", @"五菱", @"陆风", @"众泰"];
NSArray *CompanyMarks = @[@"宝马", @"BYD", @"大众", @"奔驰", @"北京"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"SELF IN %@", ChinaMarks];
NSArray *result = [CompanyMarks filteredArrayUsingPredicate:predicate];
for (id obj in result) {
NSLog(@"%@", obj);
}
注意:SELF也不区分大小写。
补充:使用SELF可方便地计算两个数组的“交集”。
4.4 字符串运算符
字符串运算符本身不区分大小写,BeginsWith等同BEGINSWITH
运算符:BEGINSWITH
是否以指定字符串开头
NSArray *books = @[@"IOS开发入门", @"精通IOS", @"IOS从入门到精通",
@"好学的IOS", @"精通IOS8"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self beginsWith 'IOS'"];
NSArray *result = [books filteredArrayUsingPredicate:predicate];
运算符:ENDSWITH
是否以指定字符串结尾
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self endsWith 'IOS'"];
运算符:CONTAINS
是否包含指定字符串
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self contains 'IOS'"];
使用修饰符:[C]
比较字符串的内容时,不区分大小写
NSArray *books = @[@"IOS开发入门", @"精通IOS", @"IOS从入门到精通",
@"好学的IOS", @"精通IOS8"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self contains [c] 'ios'"];
使用修饰符:[d]
比较字符串的内容时,忽略重音符号。
对于中文字符串,可以忽略。
NSArray *books = @[@"good", @"goods", @"goodge", @"sgooder", @"god"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self contains [d] 'good'"];
NSArray *result = [books filteredArrayUsingPredicate:predicate];
//仅@”god”不匹配。
使用修饰符:[cd]
比较字符串的内容时,不区分大小写,而且忽略重音符号。
注意:英文字符串的比较,常常使用[cd].
4.5 LIKE运算符
LIKE运算符,即“通配符”
*表示任意个字符
?表示1个字符, 一个汉字算1个字符。
实例:
NSArray *books = @[@"IOS开发入门指南", @"精通IOS", @"IOS从入门到精通",
@"好学的IOS", @"精通IOS8", @"新编IOS7入门必备"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"self like '*IOS*入门??'"];
NSArray *result = [books filteredArrayUsingPredicate:predicate];