Выбор объектов из данных ядра не в наборе
Я пытаюсь извлечь объекты из основных данных, которые не находятся в заданном наборе, но я не смог заставить его работать.
Например, предположим, что у нас есть основной объект данных с именем User, который имеет несколько атрибутов, таких как userName, familyName, givenName и active. Учитывая массив строк, представляющих набор имен пользователей, мы можем легко получить всех пользователей, соответствующих этому списку имен пользователей:
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User"
inManagedObjectContext:moc];
[request setEntity:entity];
NSArray *userNames = [NSArray arrayWithObjects:@"user1", @"user2", @"user3", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userName IN %@", userNames];
[request setPredicate:predicate];
NSArray *users = [moc executeFetchRequest:request error:nil];
Однако я хочу получить дополнение к этому набору, т.е. хочу, чтобы все пользователи в основных данных не имели имен пользователей, указанных в массиве userNames. Кто-нибудь есть идея, как подойти к этой проблеме? Я думал, что было бы достаточно просто добавить "NOT"
в предикат (i.e., "userName NOT IN %@")
, но Xcode выдает исключение, говорящее, что предикатный формат не может быть проанализирован. Я также попытался использовать построитель предикатов, доступный для запросов на выборку, без везения. Документация также не была особенно полезной. Предложения? Комментарии? Спасибо за вашу помощь:)
Ответы
Ответ 1
Чтобы найти объекты, которые не находятся в вашем массиве, все, что вам нужно сделать, это что-то вроде этого:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (userName IN %@)", userNames];
Это должно вернуть запрос всех объектов без указанных вами
Ответ 2
Я не силен в данных ядра / objective-c, но предикат должен выглядеть следующим образом:
[predicateFormat appendFormat:@"not (some_field_name in {'A','B','B','C'})"];
Пример:
NSMutableString * mutableStr = [[NSMutableString alloc] init];
//prepare filter statement
for (SomeEntity * e in self.someArray) {
[mutableStr appendFormat:@"'%@',", e.key];
}
//excluded objects exist
if (![mutableStr isEqual:@""])
{
//remove last comma from mutable string
mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy];
[predicateFormat appendFormat:@"not (key in {%@})", mutableStr];
}
//...
//use this predicate in NSFetchRequest
//fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat];
//...
Ответ 3
Вот еще один полезный пример, показывающий, как взять список строк, и отфильтровать любые, которые НЕ начинаются с букв A-Z:
NSArray* listOfCompanies = [NSArray arrayWithObjects:@"123 Hello", @"-30'c in Norway", @"ABC Ltd", @"British Rail", @"Daily Mail" @"Zylophones Inc.", nil];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF MATCHES[c] '^[A-Za-z].*')"];
NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate];
for (NSString* oneCompany in filteredList)
NSLog(@"%@", oneCompany);
Я использую этот тип NSPredicate
, когда я заполняю UITableView
индексом A-Z и хочу раздел "все остальное" для элементов, которые не начинаются с буквы.