编写NSPredicate,如果不满足条件则返回true

时间:2009-07-22 16:09:41

标签: objective-c cocoa cocoa-touch nspredicate

我目前有以下代码

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains '-'"];
[resultsArray filterUsingPredicate:pred];

这将返回一个包含' - '元素的数组。我想做相反的操作,以便返回所有不包含' - '的元素。

这可能吗?

我尝试在各个地方使用NOT关键字,但无济于事。 (根据Apple文档,我认为它无论如何都不会起作用。)

为了进一步说明这一点,是否可以为谓词提供一个我不想在数组元素中出现的字符数组? (数组是一串字符串)。

3 个答案:

答案 0 :(得分:27)

我不是Objective-C专家,而是documentation seems to suggest this is possible。你试过了吗?

predicateWithFormat:"not SELF contains '-'"

答案 1 :(得分:8)

您可以构建自定义谓词来否定您已有的谓词。实际上,您将获取现有谓词并将其包装在另一个与NOT运算符类似的谓词中:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains '-'"];
NSPredicate *notPred = [NSCompoundPredicate notPredicateWithSubpredicate:pred];
[resultsArray filterUsingPredicate:pred];

NSCompoundPredicate类支持AND,OR和NOT谓词类型,因此您可以遍历并构建一个包含阵列中不需要的所有字符的大型复合谓词,然后对其进行过滤。尝试类似:

// Set up the arrays of bad characters and strings to be filtered
NSArray *badChars = [NSArray arrayWithObjects:@"-", @"*", @"&", nil];
NSMutableArray *strings = [[[NSArray arrayWithObjects:@"test-string", @"teststring", 
                   @"test*string", nil] mutableCopy] autorelease];

// Build an array of predicates to filter with, then combine into one AND predicate
NSMutableArray *predArray = [[[NSMutableArray alloc] 
                                    initWithCapacity:[badChars count]] autorelease];
for(NSString *badCharString in badChars) {
    NSPredicate *charPred = [NSPredicate 
                         predicateWithFormat:@"SELF contains '%@'", badCharString];
    NSPredicate *notPred = [NSCompoundPredicate notPredicateWithSubpredicate:pred];
    [predArray addObject:notPred];
}
NSPredicate *pred = [NSCompoundPredicate andPredicateWithSubpredicates:predArray];

// Do the filter
[strings filterUsingPredicate:pred];
但是,我不保证它的效率,并且最好先放置可能从最终数组中消除最多字符串的字符,这样过滤器可能会使尽可能多的比较短路。

答案 2 :(得分:1)

我会按Apple documentation

中的说明推荐NSNotPredicateType