Swift 谓词只匹配值数组中的第一个值
Swift predicate only matches first value in array of values
我有一个 class 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
的记录,则只会发现第一条记录。如果我改变顺序,那么其他记录就会被识别。
我可以用数组创建谓词,但只有第一个值匹配,这似乎很奇怪。文档说值按它们出现的顺序被替换,但是它不应该继续移动到第二个值吗?
对于更多上下文,每条记录都存储在一个单独的数据库中(私有 vs public),我的 Download
class 启动两个单独的 CKQueryOperations
,它们都依赖于query
,如果 database
参数为零。 无论哪个操作失败,最终都找不到与第一个值匹配的结果,然后在检查第二个值之前放弃。
如果需要,我可以包含 'Download' 的完整代码和我失败的单元测试。
您使用了错误的谓词。您要使用 IN
操作。而不是使用字符串替换字段名称,而是使用 %K
格式说明符:
let predicate = NSPredicate(format: "%K IN %@", arguments: queryField, queryValues)
请注意,NSPredicate(format:argumentArray:)
期望参数数组中每个值的格式字符串中都有一个格式说明符。由于您的格式只有一个格式说明符,因此只有第一个值是从数组中获取的。由于您使用了 =
,该字段只是与那个值进行了比较。
Basic Comparisons
=, == The left-hand expression is equal to the right-hand expression.
=, => The left-hand expression is greater than or equal to the right-hand expression. <=, =< The left-hand expression is less than or
equal to the right-hand expression.
The left-hand expression is greater than the right-hand expression. < The left-hand expression is less than the right-hand expression. !=,
<> The left-hand expression is not equal to the right-hand expression.
字符串比较
BEGINSWITH The left-hand expression begins with the right-hand
expression.
CONTAINS The left-hand expression contains the right-hand expression.
ENDSWITH The left-hand expression ends with the right-hand expression.
LIKE The left hand expression equals the right-hand expression: ? and
- are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.
MATCHES The left hand expression equals the right hand expression
using a regex-style comparison according to ICU v3 (for more details
see the ICU User Guide for Regular Expressions).
我使用了基本比较
let resultPredicate = NSPredicate(format: "%K = %@", "key", "value")
let result_filtered = MYARRAY.filtered(using: resultPredicate) as NSArray
我有一个 class 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
的记录,则只会发现第一条记录。如果我改变顺序,那么其他记录就会被识别。
我可以用数组创建谓词,但只有第一个值匹配,这似乎很奇怪。文档说值按它们出现的顺序被替换,但是它不应该继续移动到第二个值吗?
对于更多上下文,每条记录都存储在一个单独的数据库中(私有 vs public),我的 Download
class 启动两个单独的 CKQueryOperations
,它们都依赖于query
,如果 database
参数为零。 无论哪个操作失败,最终都找不到与第一个值匹配的结果,然后在检查第二个值之前放弃。
如果需要,我可以包含 'Download' 的完整代码和我失败的单元测试。
您使用了错误的谓词。您要使用 IN
操作。而不是使用字符串替换字段名称,而是使用 %K
格式说明符:
let predicate = NSPredicate(format: "%K IN %@", arguments: queryField, queryValues)
请注意,NSPredicate(format:argumentArray:)
期望参数数组中每个值的格式字符串中都有一个格式说明符。由于您的格式只有一个格式说明符,因此只有第一个值是从数组中获取的。由于您使用了 =
,该字段只是与那个值进行了比较。
Basic Comparisons =, == The left-hand expression is equal to the right-hand expression.
=, => The left-hand expression is greater than or equal to the right-hand expression. <=, =< The left-hand expression is less than or equal to the right-hand expression. The left-hand expression is greater than the right-hand expression. < The left-hand expression is less than the right-hand expression. !=, <> The left-hand expression is not equal to the right-hand expression.
字符串比较
BEGINSWITH The left-hand expression begins with the right-hand expression.
CONTAINS The left-hand expression contains the right-hand expression.
ENDSWITH The left-hand expression ends with the right-hand expression.
LIKE The left hand expression equals the right-hand expression: ? and
- are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.
MATCHES The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).
我使用了基本比较
let resultPredicate = NSPredicate(format: "%K = %@", "key", "value")
let result_filtered = MYARRAY.filtered(using: resultPredicate) as NSArray