Как получить индекс NSArray, используя NSPredicate? - PullRequest
15 голосов
/ 29 августа 2011

Я бы знал, как получить индекс для NSArray, используя NSPredicate?

NSArray *array = [NSArray arrayWithObjects:
                  @"New-York City",
                  @"Washington DC",
                  @"Los Angeles",
                  @"Detroit",
                  nil];

Какой метод мне следует использовать, чтобы получить индекс "Los Angles", давтолько NSString
Примечание: @"Los An" или @"geles" должны возвращать тот же индекс.

Ответы [ 5 ]

21 голосов
/ 29 августа 2011

Вы должны быть в состоянии сделать это с блоками.Ниже приведен фрагмент кода (у меня нет удобного компилятора, поэтому прошу прощения за любые опечатки):

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];
                   }];

По сути, вы можете использовать метод indexOfObjectPassingTest:.Это берет блок (код, следующий за «^») и возвращает индекс для первого объекта, который соответствует вашему предикату (или NSNotFound, если совпадения не существует).Блок выполняет итерацию по каждому объекту в массиве до тех пор, пока не будет найдено совпадение (в этот момент он возвращает индекс) или не будет найдено совпадение (в этот момент он возвращает NSNotFound).Вот ссылка на программирование блока, которая может помочь вам понять логику внутри блока:

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

20 голосов
/ 29 августа 2011

Используя NSPredicate, вы можете получить массив строк, содержащих вашу строку поиска (кажется, нет встроенного метода для получения только индексов элементов):

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

Вы можете получить только индексы, используя indexesOfObjectsPassingTest:Метод:

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

Если вы хотите получить только один элемент, содержащий вашу строку, вы можете использовать аналогичный метод indexOfObjectPassingTest: для этого.

3 голосов
/ 14 мая 2014

Нашел альтернативный подход, полезный, когда поиск более сложный, так как он позволяет использовать предикат для поиска объекта, а не объект для поиска индекса:

-(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];
}
1 голос
/ 29 августа 2011

Я бы сделал это ..

NSString * stringToCompare = @"geles";
int foundInIndex;

for ( int i=0; i<[array count]; i++ ){

    NSString * tryString = [[array objectAtIndex:i] description];

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) {
        // no match
    } else {
        //match found
        foundInIndex = i;
    }



}// end for loop
0 голосов
/ 12 января 2016

На основе ответа @Louie вместо цикла for я использовал блок перечисления, который работал для меня.

Я сделал это: -

NSString *stringToCompare = @"xyz";

[myArray enumerateObjectsUsingBlock:^(id *Obj, NSUInteger idx, BOOL * _Nonnull stop) {
 NSString * tryString = [[myArray objectAtIndex:idx] description];

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) {

                // no match found

         } else {

                //match found and perform your operation. In my case i had removed array object at idx

           }
        }];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...