2012-04-15 4 views
0

Ich habe eine pList von Zeichenfolgen, die ich in einem NSMutable Array bündeln.Verwenden von characterAtidex mit Ziel C NSPredicate Klasse

Ich möchte jedes Zeichen in den Zeichenfolgen mit einem bestimmten Zeichen vergleichen und die Ergebnisse verwenden, um ein neues Array zu erstellen.

Ich bin auf den ersten und letzten Zeichen filtern, kann die folgenden

NSPredicate *filter = [NSPredicate predicateWithFormat:@"SELF beginswith[cd] %@", @"B"]; 

NSPredicate *filter = [NSPredicate predicateWithFormat:@"SELF endswith[cd] %@", @"B"]; 

verwenden, aber wenn ich versuche, die Zeichen zu lesen zwischen der characterAtIndex Methode bekomme ich einen Fehler.

NSPredicate *filter = [NSPredicate predicateWithFormat:@"SELF characterAtIndex:%i LIKE[cd] %@", 3, @"B"]; 

Ich weiß, dass ich wahrscheinlich eine Schleife zu Schleife durch jedes Wort tun könnte die Zeichen überprüft, aber unter Verwendung NSPredicate ist so viel aufgeräumter und soll viele bessere Leistung sein die Liste von Strings unter Berücksichtigung kann ziemlich groß sein (über 100.000).

Kann mir jemand die richtige Syntax für die Verwendung von CharacterAtIndex mit NSPredate zeigen oder irgendwelche anderen Lösungsideen haben?

Update: Basierend auf Kens Antwort unten verwende ich jetzt den folgenden Code, um Zeichen außerhalb der ersten und letzten Zeichen zu überprüfen. Zum Beispiel überprüft das folgende das vierte Zeichen.

NSArray *matches = [_availableWords objectsAtIndexes:[_availableWords indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){ 
    return (BOOL)([obj characterAtIndex:3] == 'R'); 
}]]; 

Allerdings, wenn ich die Spiele Array im Debugger Ich sehe die unten Fehler

matches NSArray * 0x06a67ba0 @"Variable is not a CFArray" 

und keine Objekte in dem Array gehen zu inspizieren. Basierend auf den Beispieldaten in short.plist würde ich erwarten, ein Objekt im Array zu sehen.

Vielen Dank im Voraus für jede Hilfe, Derm

Antwort

4

Die in Prädikate gebaut nicht eine solche Operation unterstützen. Sie können jedoch ein Prädikat bauen, die einen Block wertet:

NSPredicate* filter = [NSPredicate predicateWithBlock:^(id evaluatedObject, NSDictionary *bindings){ 
    return (BOOL)([evaluatedObject characterAtIndex:3] == 'B'); 
}]; 

Oder wenn Sie nur um gehen zu drehen und ein Array mit diesem Prädikat filtert, können Sie die Zwischenhändler ausgeschnitten und einen Block verwenden zu identifizieren Elemente eines Arrays direkt:

NSArray* matches = [array objectsAtIndexes:[array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop){ 
    return (BOOL)([obj characterAtIndex:3] == 'B'); 
}]]; 
+0

Danke Ken, Ya Ich möchte nur ein Array mit diesem Prädikat zu filtern. Wenn ich den zweiten Codeblock oben versuche, erhalte ich den folgenden Fehler - Inkompatible Blockzeiger senden 'int (^) (__ starke ID, NSUInteger, BOOL *)' an Parameter des Typs 'BOOL (^) (__ starke ID, NSUInteger, BOOL *) '. Irgendwelche Ideen? – dermd

+0

Ich habe die Beispiele optimiert, um den Rückgabetyp zu BOOL zu zwingen. –

+0

Danke Ken, schätze all die Hilfe dabei. Das scheint genau das zu sein, wonach ich gesucht habe. Entschuldigung, wenn das eine dumme Frage ist - ich bin ein bisschen ein Neuling zu Objective C - aber ich bekomme jetzt einen Fehler "Variable ist kein CFArray". Nachdem ich meine pList abgerufen und gebündelt habe, lege ich die Werte in ein NSMutableArray und dieses NSMutableArray versuche ich zu filtern. – dermd