Подтвердить что ты не робот

Выбор объектов из данных ядра не в наборе

Я пытаюсь извлечь объекты из основных данных, которые не находятся в заданном наборе, но я не смог заставить его работать.

Например, предположим, что у нас есть основной объект данных с именем 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 выдает исключение, говорящее, что предикатный формат не может быть проанализирован. Я также попытался использовать построитель предикатов, доступный для запросов на выборку, без везения. Документация также не была особенно полезной. Предложения? Комментарии? Спасибо за вашу помощь:)

4b9b3361

Ответ 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 и хочу раздел "все остальное" для элементов, которые не начинаются с буквы.