2014-11-06 3 views
1

Я пытаюсь построить запрос хранилища основных данных, который извлекает значения атрибута объекта, когда они встречаются в более длинной строке;Написание NSPredicate для текстового запроса 'CONTAINED_BY'

т.е. вместо того, чтобы искать случаи, когда значение атрибута содержит а (короче) строку:

request.predicate = [NSPredicate predicateWithFormat:@"carBrand contains[c] 'merced'"] 

Я хочу найти примеры (из сущности), значения атрибута найдены «содержащиеся в» произвольное (больше) строка:

NSString* textString = @"Elaine used to drive Audis, but now owns a Mercedes"; 
request.predicate = [NSPredicate predicateWithFormat:@"%@ contains[c] carBrand", textString ]; 

(т.е. получить массив, содержащий объекты с carBrand = @ "Ауди" и carBran. d = @ «Мерседес»)

В своих попытках, NSPredicate, кажется, не любит выражение с именем атрибута на правой стороне и выдает ошибку ...

[__NSCFConstantString countByEnumeratingWithState: объекты : кол-во:]: непризнанным селектор послал к экземпляру 0x

... есть способ построения такого запроса с именем атрибута на левой стороне - это «contained_by» запроса, как это мы?

PS. Поиск SO, я нашел только solutions by splitting the text into component words, который, по моему сценарию, был бы менее идеальным! Является ли это единственным типом подхода, который является жизнеспособным?

ответ

1

Постройте строку регулярных выражений с помощью массива и используйте MATCHES в своем предикате.

[NSPredicate predicateWithFormat:@"%@ MATCHES '*(Audi|Mercedes)*'", testString]; 

Для фильтрации автомобилей в зависимости от их марки:

NSArray *brands = [@"Audi", @"Mercedes"]; 
[NSPrediate predicateWithFormat:@"carBrand IN %@", brands]; 
+0

В моем примере я хочу найти *, который из многих автомобилей в моем db имеет .carBrand, которые соответствуют некоторой части строки. Разве ваш запрос не просто подтверждает, что Audi | Mercedes находится в строке? – cate

+0

Да, этот пример просто возвращает исходные строки, которые содержат либо Audi, либо Mercedes, не изменяя их. –

+0

Вопрос, отредактированный, чтобы уточнить, что желаемый результат - это * массив сущностей *, чье значение * атрибута * соответствует некоторой подстроке строки произвольного динамического поиска. – cate

0

Решил попробовать реализации componentsSeparatedByString подхода построить NSCompoundPredicate

//find alphabetic words omitting standard plurals 
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:[^a-z]*)([a-z]+?)(?:s)?\\W+" options:NSRegularExpressionCaseInsensitive error:nil]; 

//separate with pipe| and split into array 
NSString *split = [regex stringByReplacingMatchesInString:textString options:0 range:NSMakeRange(0, speciesString.length) withTemplate:@"$1|"]; 
NSArray *words = [split componentsSeparatedByString:@"|"]; 

//build predicate List 

NSMutableArray *predicateList = [NSMutableArray array]; 
for (NSString *word in words) { 
    if ([word length] > 2) { 
     NSPredicate *pred = [NSPredicate predicateWithFormat:@"brandName beginswith[c] %@", word]; 
     [predicateList addObject:pred]; 
    } 
} 
//CarBrand* object; 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
request.entity = [NSEntityDescription entityForName:@"CarBrand" inManagedObjectContext:self.managedObjectContext]; 
request.predicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateList]; 

NSError *error =nil; 
NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error]; 

Это извлекает экземпляры, найденные в тексте; eg1:

@ «Элейн привыкла управлять Аудисом, но теперь владеет Мерседесом»;

дает массив объектов, чье имя. = «Audi», «Mercedes», соответственно.

EG2: @ "Среди автомобилей были украдены Ford Mondeo, Фиат 500C и Alfa-Romeo Spyder"

дает .brandname = "Форд", "Fiat", и " Alfa Romeo "(NB no '-') соответственно.

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

Надеюсь, у кого-то будет лучшее решение!

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