Reputation: 1768
How to filter strings that start as numbers or symbols to an NSArray with NSPredicate.
example:
array = {"John", "Mary", "Aroldo", "1John", "+Mary"}
to newArray = {"1John," "+Mary"}
Upvotes: 0
Views: 830
Reputation: 1218
Here are 4 ways to do it. All of the examples make use of negated character classes. Your request was to filter out numbers and symbols, but you can also say that you want to filter out words that start with a nonalphabetic character.
- (void)testFilterArray0
{
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^a-zA-Z].*"];
filtered = [unfiltered filteredArrayUsingPredicate:predicate];
STAssertTrue([filtered isEqualToArray:expected], nil);
}
- (void)testFilteredArray1
{
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{L}].*"];
filtered = [unfiltered filteredArrayUsingPredicate:predicate];
STAssertTrue([filtered isEqualToArray:expected], nil);
}
- (void)testFilteredArray2
{
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{Letter}].*"];
filtered = [unfiltered filteredArrayUsingPredicate:predicate];
STAssertTrue([filtered isEqualToArray:expected], nil);
}
- (void)testFilteredArray3
{
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{General_Category=Letter}].*"];
filtered = [unfiltered filteredArrayUsingPredicate:predicate];
STAssertTrue([filtered isEqualToArray:expected], nil);
}
Upvotes: 6
Reputation: 18253
You can use a predicate with a regular expression to accomplish what you are after.
In general, the regex pattern you are looking for is "[chars].*"
which will match any string that begins with c, h, a, r or s - in the example. You would substitute the actual chars you want to match.
To make the construct clearer, you can make a string of the actual chars you want to match, a string with the regular expression pattern and finally, the predicate.
If you are very comfortable with regular expressions and predicates, you can of course tighten it all up to a single line of code.
NSString *matchChars = @"0123456789+-,."; // Add other characters you want to match
NSString *regexString = [NSString stringWithFormat:@"[%@].*", matchChars];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"self matches[cd] %@", regexString];
Upvotes: 0
Reputation: 3290
It doesn't use a NSPredicate, but it does the job
NSIndexSet *indexSet = [array indexesOfObjectsPassingTest:^BOOL(NSString *name, NSUInteger idx, BOOL *stop) {
unichar ch = [name characterAtIndex:0];
BOOL isLetter = (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122);
return !isLetter;
}];
NSArray *newArray = [array objectsAtIndexes:indexSet];
You might want to double check the return condition in the block, as I didn't test it.
Upvotes: 0