Reputation: 42139
The seems like an easy thing to solve, but so far I have not come up with a simple solution.
I have an NSArray that contains a few strings like the following:
NSArray *items = [NSArray arrayWithObjects:@"page_standard", @"google_map_location", @"comment", @"folder", nil];
I have a search term that is provided, but in a slightly different format:
NSString *searchTerm = @"Standard Page Format";
Another term might be:
NSString *searchTerm = @"Location Google Map";
So, even though my searchTerm
is formatted differently than the page_standard
string in my array, I still want it to match, and be able to return the index of the match.
NOTE: This isn't a user editable search. Rather, these are "codes" and "friendly names" for those code. I need to match the two so that the "friendly name" can find the matching "code".
Is this possible?
Upvotes: 0
Views: 565
Reputation: 23278
Not an exact solution to your problem. But something along these lines should do the trick.
searchTerm
. Something like,Try,
NSMutableSet *set1 = [NSMutableSet setWithArray:originalFirstWordArray];
NSMutableSet *set2 = [NSMutableSet setWithArray:searchTermArray];
[set1 intersectSet:set2];
NSArray *result = [set1 allObjects];
Based on the count of results
array, you can figure out if it matches or not. Basically you might have to compare with searchTermArray
or so.
Update: Based on your last edit, I feel that you just have to store those keywords as key value pairs in a plist and compare it when required. My above answer is suitable if the search is user editable search.
Upvotes: 0
Reputation: 21966
A computer isn't able to distinguish between two slightly different strings.What you mean here is to find "similar strings".
For this the rangeOfString method does well the job.
In the case of "google_map_location", the "Location", "Google" and "Map" strings are all substrings of "google_map_location".
At your place I would make a category with a method that looks for "similar strings".I would first divide the string in tokens using the space character as separator, then estabilish a criteria like for example, estabilish that the strings are similar if all the words are substrings of the string, also with a case insensitive compare.
Upvotes: 0
Reputation: 237010
The naive solution would be to split the strings into sets of lowercase words separated by " " and "_" and choose the set with the largest intersection. This will get you close enough to work for your test case, though you might want to refine it further for a real user-facing search feature (e.g. users might write "normal" instead of "standard", or they might want "loc" to find the location).
EDIT: Based on your comment, it looks like this is all internal rather than user-facing. In that case, the easiest solution might be to stick them all in a dictionary with "friendly names" as keys and "codes" as the corresponding values. This way it's unambiguous and you have a lot of leeway in what the "friendly names" can be.
Upvotes: 0
Reputation: 508
Try the following:
- (NSString*)find:(NSString*)term in:(NSArray*)terms {
for (NSString *item in terms) {
NSMutableSet *dictSet = [NSMutableSet set];
for (NSString *word in [item componentsSeparatedByString:@"_"]) {
[dictSet addObject:[word lowercaseString]];
}
NSMutableSet *testSet = [NSMutableSet set];
for (NSString *word in [term componentsSeparatedByString:@" "]) {
[testSet addObject:[word lowercaseString]];
}
if ([dictSet isEqualToSet:testSet]) {
return item;
}
}
return nil;
}
Upvotes: 0
Reputation: 385500
If the set of terms is known in advance, and the user chooses from a list rather than free-form text entry, just create a dictionary that maps the “friendly” terms to internal terms:
NSDictionary *internalTermForFriendlyTerm = @{
@"Standard Page Format": @"page_standard",
@"Location Google Map": @"google_map_location",
// etc.
};
...
NSString *internalTerm = internalTermForFriendlyTerm[searchTerm];
You could store the dictionary in a property list file so that it's easy to update at runtime.
Upvotes: 1