What you are looking for is a custom predicate which uses a bounded Levenshtein Distance to filter out words that are sufficiently different from a target word.
Assuming you use an implementation of Levenshtein Distance as found in this gist, your code will look approximately like this:
NSPredicate *distancePredicate = [NSPredicate predicateWithBlock:^(NSString *name, NSDictionary<NSString *, id> *bindings) {
// key is the string you're looking for (e.g. 'nink')
NSString *key = bindings[@"key"];
// Calculate the Levenshtein Distance. This may be different depending
// on how you implement it. You may want to weight matchGain and
// missingCost differently.
NSInteger score = [key compareWithWord:name matchGain:0 missingCost:1];
// Only include words that are "close enough", i.e. within two a letter
// difference.
return (BOOL)(score < 2);
}];
This predicate defines a general predicate "template", which you can then use to filter the array with the actual string you're looking for:
NSDictionary<NSString *, id> *bindings = @{@"key": @"Nink"};
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"Nick", @"Ben", @"Adam", @"Melissa", nil];
NSIndexSet *indices = [array indexesOfObjectsPassingTest:^(id object, NSUInteger index, BOOL *stop) {
return [distancePredicate evaluateWithObject:object substitutionVariables:bindings];
}];
NSArray *results = [array objectsAtIndexes:indices];
BTW, there is nothing special about the word @"key"; you can change that to be any string identifying the substitution (e.g. @"name", @"term", etc., are all valid). The key you provide in the substitution variables is the key you should use to retrieve the value.