2009-07-22 7 views
9

Al momento ho il seguente pezzo di codiceScrivere un NSPredicate che restituisce true se la condizione non è soddisfatta

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

Ciò restituisce un array con gli elementi che contengono '-'. Voglio fare l'inverso di questo in modo che tutti gli elementi che non contengono '-' vengano restituiti.

È possibile?

Ho provato a utilizzare la parola chiave NOT in varie posizioni, ma senza risultato. (Non pensavo che avrebbe funzionato comunque, basato sulla documentazione di Apple).

Per ulteriori informazioni, è possibile fornire il predicato con una serie di caratteri che non desidero essere negli elementi dell'array? (L'array è un carico di stringhe).

+0

Titolo modificato per riflettere meglio ciò che questa domanda ha richiesto. –

risposta

27

Non sono un esperto di Objective-C, ma lo documentation seems to suggest this is possible. Hai provato:

predicateWithFormat:"not SELF contains '-'" 
+0

Grazie, mi sta bene per non aver letto il documento nella sua interezza. L'unico posto in cui non ho provato non era prima di me! – JonB

+0

Contento di aver potuto aiutare. :) –

+0

+1, Sweeeeeeet! – EmptyStack

8

È possibile creare un predicato personalizzato per negare il predicato che si è già in possesso. In effetti, si sta prendendo un predicato esistente e avvolgendolo in un altro predicato che funziona come l'operatore NOT:

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

I NSCompoundPredicate supporti classe AND, OR e NOT tipi di predicato, così si potrebbe passare attraverso e costruire un predicato composto di grandi dimensioni con tutti i caratteri che non si desidera nell'array, quindi filtrare su di esso. Provare qualcosa di simile:

// 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];

faccio alcuna garanzia circa la sua efficienza, però, ed è probabilmente una buona idea di mettere i personaggi che sono in grado di eliminare il maggior numero di corde dalla matrice finale prima in modo che il filtro può cortocircuitare quanti più confronti possibili.

Problemi correlati