objective-c – 动态创建具有不同数量的属性和值的谓词
发布时间:2020-12-16 09:33:39 所属栏目:百科 来源:网络整理
导读:我有一个具有三个属性的实体:studyID:string,studyName:string和studyDate:date. 我需要为搜索创建谓词,但用户可以选择输入所有三个属性的任何可能组合,例如一个搜索在studyID和studyDate上,但不是studyName,而下一个搜索只在studyID上. 如何根据用户决
|
我有一个具有三个属性的实体:studyID:string,studyName:string和studyDate:date.
我需要为搜索创建谓词,但用户可以选择输入所有三个属性的任何可能组合,例如一个搜索在studyID和studyDate上,但不是studyName,而下一个搜索只在studyID上. 如何根据用户决定搜索的属性组合动态创建谓词? 解决方法
您需要创建一个复合谓词,其最终形式取决于用户搜索的属性.
最干净的解决方案是使用NSExpression,NSComparisonPredicate和NSCompoundPredicate在代码中构建谓词.这将允许您为每个搜索自定义谓词. 像这样的东西: -(NSPredicate *) predicateWithStudyID:(NSString *) aStudyID studyName:(NSString *) aStudyName date:(NSDate *) aDate{
NSPredicate *p;
NSMutableArray *preds=[[NSMutableArray alloc] initWithCapacity:1];
if (aDate != nil) {
NSExpression *dateKeyEx=[NSExpression expressionForKeyPath:@"studyDate"];
NSExpression *aDateEx=[NSExpression expressionForConstantValue:aDate];
NSPredicate *datePred=[NSComparisonPredicate predicateWithLeftExpression:dateKeyEx
rightExpression:aDateEx
modifier:NSDirectPredicateModifier
type:NSEqualToPredicateOperatorType
options:0];
[preds addObject:datePred];
}
if (![aStudyID isEqualToString:@""]) {
NSExpression *studyIDKeyEx=[NSExpression expressionForKeyPath:@"studyID"];
NSExpression *aStudyIDEx=[NSExpression expressionForConstantValue:aStudyID];
NSPredicate *studyIDPred=[NSComparisonPredicate predicateWithLeftExpression:studyIDKeyEx
rightExpression:aStudyIDEx
modifier:NSDirectPredicateModifier
type:NSLikePredicateOperatorType
options:NSCaseInsensitivePredicateOption];
[preds addObject:studyIDPred];
}
if (![aStudyName isEqualToString:@""]) {
NSExpression *studyNameKeyEx=[NSExpression expressionForKeyPath:@"studyName"];
NSExpression *aStudyNameEx=[NSExpression expressionForConstantValue:aStudyName];
NSPredicate *studyNamePred=[NSComparisonPredicate predicateWithLeftExpression:studyNameKeyEx
rightExpression:aStudyNameEx
modifier:NSDirectPredicateModifier
type:NSLikePredicateOperatorType
options:NSCaseInsensitivePredicateOption];
[preds addObject:studyNamePred];
}
p=[NSCompoundPredicate andPredicateWithSubpredicates:preds];
[preds release];
return p;
}
然后你会像这样使用它: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDate *firstDate=[NSDate date];
NSDate *secondDate=[firstDate dateByAddingTimeInterval:60*60*24];
NSDate *thirdDate=[secondDate dateByAddingTimeInterval:60*60*24];
// I use an array of dictionaries for convenience but it works
// for managed objects just as well.
NSDictionary *d1=[NSDictionary dictionaryWithObjectsAndKeys:
@"abc123",@"studyID",@"firstStudy",@"studyName",firstDate,@"studyDate",nil];
NSDictionary *d2=[NSDictionary dictionaryWithObjectsAndKeys:
@"abc456",@"secondStudy",secondDate,nil];
NSDictionary *d3=[NSDictionary dictionaryWithObjectsAndKeys:
@"abc789",@"thirdStudy",thirdDate,nil];
NSArray *a=[NSArray arrayWithObjects:d1,d2,d3,nil];
NSPredicate *p=[self predicateWithStudyID:@"" studyName:@"thirdStudy" date:thirdDate];
NSLog(@"p = %@",p);
NSArray *filtered=[a filteredArrayUsingPredicate:p];
NSLog(@"%@",filtered);
return YES;
}
见Predicate Programming Guide: Creating Predicate Directly in Code 更新: 下面的@DaveDelong指出,在上面的第一个代码块中,我创建的subpredicates过于复杂.在这种情况下(除执行速度之外)不需要从表达式生成子预测.而只是像往常一样构建子预测,然后像这样复合它们: -(NSPredicate *) predicateWithStudyID:(NSString *) aStudyID studyName:(NSString *) aStudyName date:(NSDate *) aDate{
NSPredicate *p;
NSMutableArray *preds=[[NSMutableArray alloc] initWithCapacity:1];
if (aDate != nil) {
NSPredicate *datePred=[NSPredicate predicateWithFormat:@"studyDate==%@",aDate];
[preds addObject:datePred];
}
if (![aStudyID isEqualToString:@""]) {
NSPredicate *studyIDPred=[NSPredicate predicateWithFormat:@"studyID Like %@",aStudyID];
[preds addObject:studyIDPred];
}
if (![aStudyName isEqualToString:@""]) {
NSPredicate *studyNamePred=[NSPredicate predicateWithFormat:@"studyName Like %@",aStudyName];
[preds addObject:studyNamePred];
}
p=[NSCompoundPredicate andPredicateWithSubpredicates:preds];
[preds release];
return p;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
