How retrieve an index of an NSArray using a NSPredicate?

Using NSPredicate you can get array of strings that contain your search string (it seems there's no built-in method to get just element indexes):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchString];
NSArray *filteredArray = [array filteredArrayUsingPredicate: predicate];

You can get only indexes using indexesOfObjectsPassingTest: method:

NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
   NSString *s = (NSString*)obj;
   NSRange range = [s rangeOfString: searchString];
   return range.location != NSNotFound;
}];

If you want to get just one element containing your string you can use similar indexOfObjectPassingTest: method for that.


You should be able to do this with blocks. Below is a snippet (I don't have a compiler handy so pls excuse any typos):

NSArray *array = [NSArray arrayWithObjects:
              @"New-York City",
              @"Washington DC",
              @"Los Angeles",
              @"Detroit",
              nil];
NSString *matchCity = @"Los";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", matchCity];
NSUInteger index = [self.array  indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
                                return [predicate evaluateWithObject:obj];
                   }];

Essentially you can use the indexOfObjectPassingTest: method. This takes a block (code following the "^") and returns the index for the first object that matches your predicate (or NSNotFound if no match exists). The block iterates through each object in the array until either a match is found (at which point it returns the index) or no match is found (at which point it returns NSNotFound). Here is a link to block programming that can help you understand the logic within the block:

https://developer.apple.com/library/ios/featuredarticles/Short_Practical_Guide_Blocks/


Found an alternative approach helpful where the search is more complex as it allows predicate to be used to find object then object to find index:

-(NSIndexPath*) indexPathForSelectedCountry{
    NSUInteger indexToCountry = 0;
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isoCode = %@",self.selectedCountry.isoCode];
    NSArray * selectedObject = [self.countryList filteredArrayUsingPredicate:predicate];
    if (selectedObject){
        if (self.searchDisplayController.isActive){
            indexToCountry = [self.searchResults indexOfObject:selectedObject[0]];
        }else{
            indexToCountry = [self.countryList indexOfObject:selectedObject[0]];
        }
    }
    return [NSIndexPath indexPathForRow:indexToCountry inSection:0];
}