Предикат Swift соответствует только первому значению в массиве значений
У меня есть класс Download
который служит оберткой для CKQueryOperation
, Один из элементов позволяет мне построить свой предикат с массивом значений:
init(type: String, queryField: String, queryValues: [CKRecordValue], to rec: RecievesRecordable, from database: CKDatabase? = nil) {
let predicate = NSPredicate(format: "\(queryField) = %@", argumentArray: queryValues)
query = CKQuery(recordType: type, predicate: predicate)
reciever = rec
db = database
super.init()
}
Когда я проверю это, query
соответствует только первому значению в массиве. Так что если queryValues = [testValue0, testValue1]
и у меня есть одна запись, чьи поля соответствуют testValue0
и у меня есть вторая запись, которая соответствует testValue1
только первая запись будет обнаружена. Если я переключу порядок, то другая запись будет распознана.
Кажется странным, что я могу создать предикат с массивом, но сопоставляется только первое значение. В документации сказано, что значения подставляются в том порядке, в котором они появляются, но разве не следует перейти к второму значению?
Для большего контекста, каждая запись хранится в отдельной базе данных (частной и общедоступной) и мой Download
класс запускает два отдельных CKQueryOperations
что оба полагаются на query
, если database
параметр остался ноль. В зависимости от того, что произойдет, операция не найдет результатов, соответствующих первому значению, а затем сдастся, прежде чем проверять второе значение.
Я могу включить полный код для "Скачать" и мой провал модульный тест, если это необходимо.
2 ответа
Вы используете неправильный предикат. Вы хотите использовать IN
операция. И вместо использования замены строки для имени поля, используйте %K
спецификатор формата:
let predicate = NSPredicate(format: "%K IN %@", arguments: queryField, queryValues)
Обратите внимание, что NSPredicate(format:argumentArray:)
ожидает, что в строке формата будет один спецификатор формата для каждого значения в массиве аргументов. Поскольку у вашего формата был только один спецификатор формата, из массива было взято только первое значение. И так как вы использовали =
поле просто сравнивали с этим одним значением.
Основные сравнения=, == Левое выражение равно правому.
=, => Левое выражение больше или равно правому выражению. <=, =< Левое выражение меньше или равно правому выражению. Левое выражение больше правого. < Левое выражение меньше правого. !=,<> Левое выражение не равно правому выражению.
Сравнение строк
НАЧИНАЕТСЯ Левое выражение начинается с правого выражения.
CONTAINS Левое выражение содержит правое выражение.
ENDSWITH Левое выражение заканчивается правым выражением.
LIKE Левое выражение равно правому: ? а также
- разрешены как подстановочные знаки, где ? соответствует 1 символу, а * соответствует 0 или более символам.
СОВПАДЕНИЯ Левое выражение равняется правому выражению с использованием сравнения в стиле регулярных выражений в соответствии с ICU v3 (дополнительную информацию см. в Руководстве пользователя ICU по регулярным выражениям).
Я использовал базовые сравнения
let resultPredicate = NSPredicate(format: "%K = %@", "key", "value")
let result_filtered = MYARRAY.filtered(using: resultPredicate) as NSArray
Дополнительная информация: Руководство по программированию предикатов