复合谓词 NSPredicate
Posted
技术标签:
【中文标题】复合谓词 NSPredicate【英文标题】:CompoundPredicate NSPredicate 【发布时间】:2016-04-22 11:10:15 【问题描述】:例如,我有三个 NSPredicate。
NSPredicate *pred1 = [NSpredicate ...];
NSPredicate *pred2 = [NSpredicate ...];
NSPredicate *pred3 = [NSpredicate ...];
我从服务器字符串中获得了我需要组合谓词的方式。
举例
(1 OR 2 OR 3)
(1 OR 3) AND 2
3 OR (1 AND 2)
如何在正确的条件下结合我的三个谓词并给出括号?
谢谢
【问题讨论】:
【参考方案1】:你总是可以像这样创建嵌套的NSCompoundPredicate
NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[firstPredicate, secondPredicate]];
NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[thirdPredicate, fourthPredicate]];
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[orPredicate, andPredicate]];
【讨论】:
每次我可以有不同的字符串。而且我不能有三个,例如十个(1 OR 2 AND (3 OR 4) AND (5 OR 6) AND 7 AND 8 AND 10) 你总是可以组合那些不在大括号内的,对吧?像这样:(2 AND 7 AND 8 AND 10 AND (3 OR 4) AND (5 or 6) OR 1)。现在你可以像这样进行谓词:NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[2,7,8,10]];
等等......【参考方案2】:
一种方法是从您的谓词中创建一个“真值表输入”,根据字符串创建一个组合谓词,并使用真值表数据对其进行评估。
为了使谓词在真值表上起作用,您需要将(1 OR 2) AND 3
转换为(SELF[1]==YES OR SELF[2]==YES) AND SELF[3]==YES
格式。你可以用正则表达式来做到这一点:
NSString *combine = @"(1 OR 2) AND 3";
NSError *err;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:@"\\d+"
options:0
error:&err];
NSString *subst = [regex
stringByReplacingMatchesInString:combine
options:0
range:NSMakeRange(0, combine.length)
withTemplate:@"SELF[$0]==YES"];
NSLog(@"%@", subst);
接下来,你可以构建NSPredicate
:
NSPredicate *pred = [NSPredicate predicateWithFormat:subst];
最后,你需要建立你的真值表。逐一评估谓词,并将结果放入NSArray
。将未使用的元素放在索引 0 处,因为您的替换字符串使用从 1 开始的索引。
现在您可以使用之前准备的谓词了:
NSArray *data1 = @[@(NO), @(YES), @(NO), @(YES)];
NSArray *data2 = @[@(NO), @(NO), @(NO), @(YES)];
NSLog(@"%d", [pred evaluateWithObject:data1]); // Prints 1
NSLog(@"%d", [pred evaluateWithObject:data2]); // Prints 0
我为真值表data1
和data2
使用了固定值。您需要评估谓词pred1
..predN
,并将结果放入NSArray
的位置1..N。
【讨论】:
对不起,我在 NSPredicate *pred = [NSPredicate predicateWithFormat:subst];之后没看懂; NSPredicate pred = [NSPredicate predicateWithFormat:subst]; NSMutableArray *resultArray = [NSMutableArray new]; [resultArray addObject:@(NO)]; NSPredicate *currentPred1 = *; NSPredicate *currentPred2 = *; NSPredicate *currentPred3 =]; NSArray *arrayPredicates = @[currentPred1, currentPred2, currentPred3]; for (int i = 0; i @Alexander 这几乎是对的,除了 `[resultArray addObject:@([pred evaluateWithObject:arrayPredicates[i]])]` 应该是[resultArray addObject:@([arrayPredicates[i] evaluateWithObject:someObject])]
,其中 someObject
是您传递的对象到您的pred1
..predN
进行评估。 for
循环也需要 i < arrayPredicates.count
,而不仅仅是 i < arrayPredicates
Да,спасибобольшое! Попробовал вас найти, хотел с вами связаться, по почте например, но не получилось。【参考方案3】:
您可以使用以下代码:
NSPredicate *p1 = [NSPredicate ];
NSPredicate *p2 = [NSPredicate "];
NSPredicate *p3 = [NSPredicate "];
在最终谓词中
NSPredicate *p = [NSCompoundPredicate andPredicateWithSubpredicates: @[p1, p2,p3]];
这个工作就像 (p1 AND p2 AND p3)
你也可以使用 orPredicateWithSubpredicates,notPredicateWithSubpredicate 和 nscompoundpredicate
【讨论】:
以上是关于复合谓词 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章