2013-11-22 2 views
1

В моем приложении iOS я реализовал табличный вид из основных данных и строки поиска. В текущем статусе поиск показывает только поля, начинающиеся с строки поиска, но я хочу показать поля, содержащие текст поиска длиной не менее трех символов.Параметры NSComparisonResult

That's мой код для функции поиска:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope 
{ 
    NSLog(@"Previous Search Results were removed."); 
    [self.searchResults removeAllObjects]; 

    for (Person *person in [self.fetchedResultsController fetchedObjects]) 
    { 
     if ([scope isEqualToString:@"All"] || [person.firstname isEqualToString:scope]) 
     { 
      NSComparisonResult result = [person.firstname compare:searchText 
                options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) 
                range:NSMakeRange(0, [searchText length])]; 
      if (result == NSOrderedSame) 
      { 
       NSLog(@"Adding person.firstname '%@' to searchResults as it begins with search text '%@'", person.firstname, searchText); 
       [self.searchResults addObject:person]; 
      } 
     } 
    } 
} 

Просит Вас научить меня способом сделать поиск в розыске, любое поле, которое имеет строку поиска по крайней мере трех символов в длина. Спасибо.

+0

Stupid комментарий, я уверен, но Вы, вероятно, означает, содержит, по меньшей мере, три символа из строки поиска в том же порядке, как они появляются в строке поиска ? Таким образом, строка поиска может быть «abcdef», и это будет соответствовать «stcdepqr», но не «edabfc»? – Tommy

+0

Да, вы правы, извините .... спасибо tommy:) Пример: строка поиска: # 10, выбранные поля: task # 10/group # 101 и т. Д. – mvasco

+2

Означает ли это, что searchText # 10 будет сопоставлен с # 0120, поскольку он соответствует 3 символам из searchText или вы ищете 3 последовательных символа? –

ответ

1

Самый простой способ, лучше всего подходит для ваших требований, на мой взгляд было бы использовать NSPredicate, чтобы отфильтровать [self.fetchedResultsController fetchedObjects] массив и используй это. NSPredicate может быть применен в любом NSArray, чтобы отфильтровать его результаты, отправив сообщение filteredArrayUsingPredicate: этому экземпляру массива. Поэтому мое предложение заключается в использовании какой-то код, как следующее:

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { 
self.searchResults = [[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
    Person* person = evaluatedObject; 
    NSString* firstName = person.firstname; 

    //searchText having length < 3 should not be considered 
    if (!!searchText && [searchText length] < 3) { 
     return YES; 
    } 

    if ([scope isEqualToString:@"All"] || [firstName isEqualToString:scope]) { 
     return ([firstName rangeOfString:searchText].location != NSNotFound); 
    } 
    return NO; //if nothing matches 
    }]]; 
} 
+0

спасибо Ayan, но я должен спросить вас, где я должен вставить ваш код. ?? – mvasco

+1

@mvasco, пожалуйста, см. Мой отредактированный ответ с модифицированным методом 'filterContentForSearchText' для вас. –

+0

Еще раз спасибо Ayan, но с помощью вашего кода не отображается фильтрация. Нет сообщения об ошибке, и приложение не зависает. Например: 10 записей, каждая запись имеет первое имя, содержимое полей firstname: 1. task # 1 2. task # 2 3. task # 3 и т. Д. Запуск с моим кодом, я должен поиск всей строки, например: task # -> показывает все 10 записей; задача № 1 -> показывает записи 1 и 10, задачу № 1 и задачу № 10. Запуск с вашим кодом, если я ищу: task # 1 -> показать все записи ... – mvasco

1

Чтобы начать обсуждение, по крайней мере, наивно перебором подход:

// get a set of all substrings; using a set means these will be deduplicated 
NSMutableSet *substrings = [NSMutableSet set]; 
for(NSInteger index = 0; index < searchText.length - 3; index++) 
    [substrings addObject:[searchText substringWithRange:NSMakeRange(index, 3)]]; 

// search every person for every single last possibility 
[self.searchResults removeAllObjects]; 
for(Person *person in [self.fetchedResultsController fetchedObjects]) 
{ 
    // ... scope and whatever else tests here ... 

    for(NSString *string in substrings) 
    { 
     if([person.firstname rangeOfString:string].location != NSNotFound) 
     { 
      [self.searchResults addObject:person]; 
      break; // exit the string in substrings loop early 
     } 
    } 
} 
+0

спасибо Tommy, позвольте мне попробовать ваше предложение .... :) Я скажу вам .. – mvasco

+0

Tommy, я получаю сообщение об ошибке: No visible @interface для NSString объявляет селектор rangeOfSubstring. А какая часть моего кода должна быть заменена вашим предложением? – mvasco

+1

Извините; Я просто набрал его здесь напрямую и, очевидно, более ранний вызов 'substringWithRange:' повлиял на мое мышление. Это 'rangeOfString:', а не 'rangeOfSubstring:', поскольку вещь, которую вы передаете, необязательно является подстрокой - она ​​вообще не может быть найдена. – Tommy

Смежные вопросы