Я много оглядывался, но так и не смог найти ответ на этот вопрос ...

В моем приложении есть класс, содержащий произношение китайского пиньинь , настроенное как произношение # [пробел] произношение # например, 你好 [привет] будет ni3 hao3

Итак, мой вопрос: как я могу заставить NSPredicate игнорировать числа в строке / классе во время поиска?

В идеале я мог бы искать: " nihao " « ни хао » и т.д

И все равно получите тот же результат ( 你好 ni3 hao3 )

Я пробовал несколько экземпляров LIKE , но каждый раз терпел неудачу ...

Благодарность

Вот мой массив по запросу:

     -(NSMutableArray *) wordList{
    cdh = [[NSMutableArray alloc] initWithCapacity:10];
    @try {
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"cdh.sqlite"];
        BOOL success = [fileMgr fileExistsAtPath:dbPath];
        if(!success)
        {
            NSLog(@"Cannot locate database file '%@'.", dbPath);
        }
        if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
        {
            NSLog(@"An error has occured: %s", sqlite3_errmsg(db));

        }


        const char *sql = "SELECT * FROM MAIN";
        sqlite3_stmt *sqlStatement;
        if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
        {
            NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(db));
        }else{

            while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
                Words * word = [[Words alloc] init];
                word.head = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,0)];
                word.pro = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
                word.def = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];
                [cdh addObject:word];
            }
        }
         sqlite3_finalize(sqlStatement);
    }
    @catch (NSException *exception) {
        NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(db));
    }
    @finally {
        sqlite3_close(db);
        return cdh;

    }
}

Words.h

#import <Foundation/Foundation.h>
#import "TestViewController.h"

@interface Words : NSObject {
NSString *head;
NSString *pro;
NSString *def;
}

@property(nonatomic, copy) NSString *head;
@property(nonatomic, copy) NSString *pro;
@property(nonatomic, copy) NSString *def;

@end

Words.m

#import "Words.h"

@implementation Words

@synthesize head;
@synthesize pro;
@synthesize def;

- (NSString *)searchableStringValue {
NSCharacterSet *invalidSet = [[NSCharacterSet characterSetWithCharactersInString:@"[]0123456789 "] invertedSet];
NSString *searchString = [[pro componentsSeparatedByCharactersInSet:invalidSet] componentsJoinedByString:@""];
    return searchString;
}

@end

TestViewController.h

#import <UIKit/UIKit.h>
#import <sqlite3.h>
#import "Words.h"

    @interface TestViewController : UITableViewController {
    NSMutableArray *cdh;
    sqlite3 * db;
}
@property(nonatomic,retain) NSMutableArray *cdh;
@property (nonatomic, strong) NSData *myData;

-(NSMutableArray *) wordList;

@end

TestViewController.m (включая предикат)

    - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
    {
        NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"(head beginswith[c] %@) OR (searchableStringValue beginswith[c] %@)", searchText, searchText];
        searchResults = [cdh filteredArrayUsingPredicate:resultPredicate];
    }

    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
    {
        [self filterContentForSearchText:searchString
                                   scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                          objectAtIndex:[self.searchDisplayController.searchBar
                                                         selectedScopeButtonIndex]]];

        return YES;
    }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
    // Return the number of rows in the section.
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [searchResults count];
    } else {
    return [self.cdh count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
//    int rowCount = indexPath.row;

//    Words *word = [self.cdh objectAtIndex:rowCount];
//    cell.textLabel.text = word.head;
 //   cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ %@", word.pro, word.def];

    // Configure the cell...
    Words *word = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        word = [searchResults objectAtIndex:indexPath.row];
    } else {
        word = [cdh objectAtIndex:indexPath.row];
    }

    cell.textLabel.text = word.head;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ %@", word.pro, word.def];
    return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"ShowWordDetails"]) {
    NSIndexPath *indexPath = nil;
    Words *word = nil;

    if (self.searchDisplayController.active) {
        indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
        word = [searchResults objectAtIndex:indexPath.row];
    } else {
        indexPath = [self.tableView indexPathForSelectedRow];
        word = [cdh objectAtIndex:indexPath.row];
    }

    DetailsViewController *destViewController = segue.destinationViewController;
    destViewController.word = word;
}
}
0
Mou某 18 Фев 2014 в 15:34
Как хранятся ваши струны? В словаре / пользовательском объекте / Core Data?
 – 
Wain
18 Фев 2014 в 15:36
Не уверен, что если честно, вроде новичок во всем этом ... строки загружаются из базы данных sqlite [не уверен, что это то, о чем вы спрашиваете], а затем сохраняются в массиве
 – 
Mou某
18 Фев 2014 в 15:53
Можете ли вы зарегистрировать образец массива и добавить его к вопросу, пожалуйста (возможно, с небольшим кодом, показывающим, что вы сделали для создания журнала).
 – 
Wain
18 Фев 2014 в 15:56
Извините, что я полный дебил, но я не совсем уверен, что вы имеете в виду, прося меня записать образец массива ...
 – 
Mou某
18 Фев 2014 в 16:05
Ваши строки находятся в массиве, который вы говорите - регистрируйте содержимое массива (чтобы мы могли видеть / проверять, что это просто строки или некоторые объекты-контейнеры). Образец относится к относительно небольшому подмножеству всего, что есть в вашей базе данных.
 – 
Wain
18 Фев 2014 в 16:07

1 ответ

Лучший ответ

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

Например, рассмотрите возможность добавления метода, который возвращает:

- (NSString *)searchableStringValue

Этот метод примет строку, которую вы сейчас пытаетесь найти, и изменит ее, чтобы удалить скобки, числа и пробелы. Проще всего этого добиться с помощью:

NSCharacterSet *invalidSet = [[NSCharacterSet characterSetWithCharactersInString:@"[]0123456789 "] invertedSet];
NSString *searchString = [[##XXX## componentsSeparatedByCharactersInSet:invalidSet] componentsJoinedByString:@""];

Где ## XXX ## - строка, которую вы сейчас пытаетесь найти.

Теперь ваш предикат должен использовать searchableStringValue вместо строки, которую вы сейчас пытаетесь найти.

1
Wain 18 Фев 2014 в 17:06
Как ссылаться на word.pro в части ## XXX ##? Я пробовал word.pro и self.word.pro, но, похоже, не подключается ...
 – 
Mou某
18 Фев 2014 в 20:00
self.pro, потому что он находится внутри класса Words, а word - это другая ссылка на экземпляр ...
 – 
Wain
18 Фев 2014 в 20:05
P.s. Добро пожаловать в переполнение стека. Не забывайте голосовать за ответы, которые помогают, и отмечать ответы, которые решают вашу проблему ;-)
 – 
Wain
18 Фев 2014 в 20:07
Большое спасибо за вашу помощь, я чувствую себя дождевым человеком в кондитерской;) Я получаю сообщение об ошибке, в котором говорится, что «pro» - это не типизированный объект, найденный на моем контроллере ... какие-нибудь идеи?
 – 
Mou某
18 Фев 2014 в 20:16
1
Удален инвертированный набор: вот код, который я наконец-то получил: - (NSString *)searchableStringValue { NSCharacterSet *invalidSet = [NSCharacterSet characterSetWithCharactersInString:@"1234 "]; NSString *searchString = [[pro componentsSeparatedByCharactersInSet:invalidSet] componentsJoinedByString:@""]; return searchString; } наконец, еще раз большое спасибо за вашу помощь!
 – 
Mou某
21 Фев 2014 в 11:10