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

Jon*_*onB 9 cocoa cocoa-touch objective-c nspredicate

我目前有以下代码

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains '-'"];
[resultsArray filterUsingPredicate:pred];
Run Code Online (Sandbox Code Playgroud)

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

这可能吗?

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

为了进一步说明,是否有可能为谓词提供一个字符数组,我不想在数组的元素中?(数组是一串字符串).

Joh*_*lla 27

我不是Objective-C专家,但文档似乎表明这是可能的.你有没有尝试过:

predicateWithFormat:"not SELF contains '-'"
Run Code Online (Sandbox Code Playgroud)


Tim*_*Tim 8

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

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF contains '-'"];
NSPredicate *notPred = [NSCompoundPredicate notPredicateWithSubpredicate:pred];
[resultsArray filterUsingPredicate:pred];
Run Code Online (Sandbox Code Playgroud)

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];
Run Code Online (Sandbox Code Playgroud)

但是我不保证它的效率,并且最好先将最终阵列中可能消除大多数字符串的字符放在一起,这样滤波器就可以将尽可能多的比较短路.