Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use an NSPredicate to select an exact phrase from an array?

I am using an NSPredicate to filter an NSDictionary by a list of states and countries.

All the data are stored in a comma separated array: @"Alabama", @"Alaska", @"Arizona", @"Arkansas", @"California", @"Colorado", etc

However, there are 2 situations where duplicates are occurring. The state "New Mexico" contain the word "Mexico", and "Arkansas" contains the word "Kansas.

Here's the basic code I'm using to define the predicate.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location contains[c] %@", @"Kansas"];

How can I make sure "Kansas" doesn't return objects with "Arkansas"? Using BEGINSWITH or LIKE doesn't work because the list begins with some other state.

Thanks!

like image 330
Jonah Avatar asked Jun 27 '14 21:06

Jonah


2 Answers

Let's see if I understand correctly. You have a dictionary, where there is a key "Location" whose object is a string with comma separated state names. Sounds like you need a regular expression to match.

NSString* expr = [NSString stringWithFormat:@"^%1$@.*|.*, %1$@.*", @"Kansas"]  
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"Location MATCHES[c] %@", expr];

Now, here is how it would behave for different examples:

@{@"Location": @"Kansas, Arkansas, Alabama"} //Pass
@{@"Location": @"Alabama, Kansas"} //Pass
@{@"Location": @"Arkansas, Alabama"} //Fail

The regular expression ^%1$@.*|.*, %1$@.* tests if the word provided is either at the start of the string or followed by characters and ", ", which puts it in the middle. %1$@ takes the first param, so that it can be used multiple times instead of prividing the same string several times.

like image 86
Léo Natan Avatar answered Sep 28 '22 16:09

Léo Natan


May be this helps?

// If I understood correctly, then your locations in the dictionary are like this
NSString *locations = @"Alabama, Alaska, Arizona, Arkansas";

NSString *trimmedLocations = [locations stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray *compoments = [[trimmedLocations componentsSeparatedByString:@","] mutableCopy];   
//now in components we have this: @[@"Alabama", @"Alaska", @"Arizona", @"Arkansas", @"California", @"Colorado"]

[compoments filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString *evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject isEqualToString:@"Kansas"];
}]];

BOOL match = compoments.count;
if (match) {
    //do something with locations...
}
like image 37
arturdev Avatar answered Sep 28 '22 16:09

arturdev