2011-06-22 10 views
1

私は(plistの中)のデータ構造を持っている:検索NSArrayの

enter image description here

何私がここに持っていることはNSDictionaryNSArrayです。

Title 
Link (recursive) 

これはすなわち、いくつかの枝がレベル0で死ぬことができる可変長分岐を有する、構造のようなツリーを形成し、いくつかはレベル3以上と大きくすることができる:各NSDictionaryは、2つのキーを有しています。

私はこの構造をUITableViewに示しています(少しの助けを借りてUINavigationControllerから)。これは十分に簡単でした。

注:リーフノード タッピングオン(「リンク」としてゼロニル又はNSDictionaryオブジェクト によって表される)、 イベントは、いくつかの情報が表示され すなわちモデルウィンドウがトリガされます。

ここで、検索サポートを追加する必要があります。

検索バーは、UITabeView(レベル0)の上に表示されます。構造のようにこのツリーを検索し、結果をUISearchDisplayControllerを使って表示し、ユーザーが結果をナビゲートできるようにする方法を考え出す必要があります。

どのように...私はちょっと固まっています。 とアドバイスが必要です。

と入力すると検索が必要なため、検索が迅速に行われる必要があります。

p.s.このデータ構造をCoreDataに変換することを考えましたが、それはまだ私の心の中に潜んでいます。この場合に役立つと思われる場合は、アドバイスをお願いします。


編集:ここで(途中で)働いている私の現在のソリューション、です :

#pragma mark - 
#pragma mark UISearchDisplayController methods 

- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar { 
    NSLog(@"%s", __FUNCTION__); 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
    NSLog(@"%s", __FUNCTION__); 
    [self filterCategoriesForSearchText:searchString 
           scope:[controller.searchBar selectedScopeButtonIndex]]; 

    // Return YES to cause the search result table view to be reloaded. 
    return YES; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { 
    NSLog(@"%s", __FUNCTION__); 
    [self filterCategoriesForSearchText:[controller.searchBar text] 
           scope:[controller.searchBar selectedScopeButtonIndex]]; 

    // Return YES to cause the search result table view to be reloaded. 
    return YES; 
} 

#pragma mark UISearchDisplayController helper methods 

- (void)filterCategoriesForSearchText:(NSString *)searchText scope:(NSInteger)scope { 
    self.filteredCategories = [self filterCategoriesInArray:_categories forSearchText:searchText]; 

    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:KEY_DICTIONARY_TITLE ascending:YES] autorelease]; 
    [self.filteredCategories sortUsingDescriptors:[NSArray arrayWithObjects:descriptor, nil]]; 
} 

- (NSMutableArray *)filterCategoriesInArray:(NSArray *)array forSearchText:(NSString *)searchText { 
    NSMutableArray *resultArray = [NSMutableArray array]; 
    NSArray *filteredResults = nil; 

    // Apply filter to array 
    // For some weird reason this is not working. Any guesses? [NSPredicate predicateWithFormat:@"%@ CONTAINS[cd] %@", KEY_DICTIONARY_TITLE, searchText]; 
    NSPredicate *filter = [NSPredicate predicateWithFormat:@"Title CONTAINS[cd] %@", searchText]; 
    filteredResults = [array filteredArrayUsingPredicate:filter]; 

    // Store the filtered results (1) 
    if ((filteredResults != nil) && ([filteredResults count] > 0)) { 
     [resultArray addObjectsFromArray:filteredResults]; 
    } 

    // Loop on related records to find the matching results 
    for (NSDictionary *dictionayObject in array) { 
     NSArray *innerCategories = [dictionayObject objectForKey:KEY_DICTIONARY_LINK]; 

     if ((innerCategories != nil) && ([innerCategories count] > 0)) { 
      filteredResults = [self filterCategoriesInArray:innerCategories forSearchText:searchText]; 

      // Store the filtered results (2) 
      if ((filteredResults != nil) && ([filteredResults count] > 0)) { 
       [resultArray addObjectsFromArray:filteredResults]; 
      } 
     } 
    } 

    return resultArray; 
} 

答えて

1

コアデータを、かなり効率的にデータストア内の検索を実行することができるだろうと効率的に検索を拡大することができます。また、TableViewにNSFetchedResultsControllerを使用すると、メモリー効率はほぼ確実です。最悪の場合は、常に1つのレベル配列しかロードされません。そして、最良のケースはかなり良いです。配列にはわずか数個のオブジェクトしかありません。 HTH

関連する問題