Каков наилучший способ создания сложного NSCompoundPredicate?

Мне нужно построить NSPredicate со многими фрагментами данных. Например, в SQL я бы сделал что-то вроде следующего:

SELECT * 
  FROM TRANSACTIONS
  WHERE CATEGORY IN (categoryList)
    AND LOCATION IN (locationList)
    AND TYPE IN (typeList)
    AND NOTE contains[cd] "some text"
    AND DATE >= fromDate
    AND DATE <+ toDate

Я борюсь с тем, как построить это как NSPredicate для использования с Core Data. Я прочитал документацию... которая дает лишь упрощенные примеры. Если кто-нибудь может указать мне на более сложный пример, я бы, конечно, его оценил.


Хорошо, у меня был ответ здесь в течение двух лет, что многие люди нашли полезными. Мой пост был удален. Вот обновленный URL с решением.

https://www.radeeccles.com/convert-sql-statement-to-an-nspredicate-for-use-with-core-data/

Ответ 1

Что вам нужно сделать, так это создать предикат для каждого из ваших предложений. Например, расставьте свой запрос:

  • ВЫБОР * ОТ ОПЕРАЦИЙ
  • WHERE CATEGORY IN (categoryList)
  • И LOCATION IN (locationList)
  • И TYPE IN (typeList)
  • И ПРИМЕЧАНИЕ содержит [cd] "некоторый текст"
  • И DATE >= fromDate И DATE < + toDate

Исходя из этого, у вас есть 5 предикатов (2-6). Так что пусть работа над ними одна за другой.

 NSPredicate *inCategoryPredicate = [NSPredicate predicateWithFormat:@"Category IN %@", categoryList];

 NSPredicate *locationPredicate = [NSPredicate predicateWithFormat:@"Location IN %@", locationList];

 NSPredicate *typePredicate = [NSPredicate predicateWithFormat:@"Type IN %@", typeList];

 NSPredicate *notePredicate = [NSPredicate predicateWithFormat:@"Note contains[c] %@", @"Some Text"];

 NSPredicate *startDatePredicate = [NSPredicate predicateWithFormat:@"Date => @", fromDate];

 NSPredicate *endDatePredicate = [NSPredicate predicateWithFormat:@"Date <= @", toDate];

Теперь вам просто нужно объединить их в один предикат: Состояние документации Apple:

Вы должны структурировать составные предикаты, чтобы свести к минимуму количество работа выполнена. Регулярное выражение, в частности, является дорогостоящим операция. В сложном предикате вы должны выполнять простые тесты перед регулярным выражением;

Сказав это, вы должны сначала начать с "простых" предикатов. Итак:

NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: startDatePredicate, endDatePredicate, inCategoryPredicate, locationPredicate, typePredicate, notePredicate];

Вы всегда можете получить представление о том, как выглядит предикат (sql where), если вы NSLog его.