子查询中的 NSPredicate
NSPredicate Inside a SUBQUERY
我正在尝试为 NSPredicate 编写 SUBQUERY。我的问题是我手头没有 SUBQUERY 的谓词部分的查询。有没有办法在 SUBQUERY 中嵌套 NSPredicate?
例如,这是我尝试过的:
let ordersPredicate = NSPredicate()//some predicate passed in
//how do I use the ordersPredicate inside the subquery??
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x,'%@').@count > 0", ordersPredicate.predicateFormat)
更新:我现在不得不通过执行第一个谓词并执行 ANY IN 查询来做一个肮脏的解决方法。它很蹩脚 :( 因为我在其他地方以及稍后在管道中执行 ordersPredicate ..
let fetchRequest = NSFetchRequest()//blah
fetchRequest.predicate = orderPredicate
let orders = //execute fetch
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, ANY $x in %@).@count > 0", orders)
感谢@Willeke 的一些指点,我能够想出一个解决方案。
public extension NSPredicate{
public func stringForSubQuery(prefix:String) -> String{
var predicateString = ""
if let predicate = self as? NSCompoundPredicate{
for (index, subPredicate) in predicate.subpredicates.enumerate(){
if let subPredicate = subPredicate as? NSComparisonPredicate{
predicateString = "\(predicateString) \(prefix)\(subPredicate.predicateFormat)"
}
else if let subPredicate = subPredicate as? NSCompoundPredicate{
predicateString = "\(predicateString) (\(subPredicate.stringForSubQuery(prefix)))"
}
//if its not the last predicate then append the operator string
if index < predicate.subpredicates.count - 1 {
predicateString = "\(predicateString) \(getPredicateOperatorString(predicate.compoundPredicateType))"
}
}
}
return predicateString
}
private func getPredicateOperatorString(predicateType: NSCompoundPredicateType) -> String{
switch(predicateType){
case .NotPredicateType: return "!"
case .AndPredicateType: return "&&"
case .OrPredicateType: return "||"
}
}
}
这是用法
let ordersPredicate = NSPredicate()//some predicate passed in
let ordersPredicateFormat = orderPredicate.stringForSubQuery("$x.")
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, \(ordersPredicateFormat)).@count > 0")
对于以后遇到这种情况的任何人,您无需自己构建谓词字符串,只需在子查询字符串中直接使用 predicateFormat
即可。它已经被正确转义,所以使用字符串插值。
let ordersPredicate = NSPredicate()
// Add it to the query with string interpolation
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, \(ordersPredicate.predicateFormat)).@count > 0")
如果您尝试将其作为参数传递,它会再次尝试对字符串进行转义,这可能不起作用。
// Don't do this!
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, %@).@count > 0", ordersPredicate.predicateFormat)
我正在尝试为 NSPredicate 编写 SUBQUERY。我的问题是我手头没有 SUBQUERY 的谓词部分的查询。有没有办法在 SUBQUERY 中嵌套 NSPredicate?
例如,这是我尝试过的:
let ordersPredicate = NSPredicate()//some predicate passed in
//how do I use the ordersPredicate inside the subquery??
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x,'%@').@count > 0", ordersPredicate.predicateFormat)
更新:我现在不得不通过执行第一个谓词并执行 ANY IN 查询来做一个肮脏的解决方法。它很蹩脚 :( 因为我在其他地方以及稍后在管道中执行 ordersPredicate ..
let fetchRequest = NSFetchRequest()//blah
fetchRequest.predicate = orderPredicate
let orders = //execute fetch
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, ANY $x in %@).@count > 0", orders)
感谢@Willeke 的一些指点,我能够想出一个解决方案。
public extension NSPredicate{
public func stringForSubQuery(prefix:String) -> String{
var predicateString = ""
if let predicate = self as? NSCompoundPredicate{
for (index, subPredicate) in predicate.subpredicates.enumerate(){
if let subPredicate = subPredicate as? NSComparisonPredicate{
predicateString = "\(predicateString) \(prefix)\(subPredicate.predicateFormat)"
}
else if let subPredicate = subPredicate as? NSCompoundPredicate{
predicateString = "\(predicateString) (\(subPredicate.stringForSubQuery(prefix)))"
}
//if its not the last predicate then append the operator string
if index < predicate.subpredicates.count - 1 {
predicateString = "\(predicateString) \(getPredicateOperatorString(predicate.compoundPredicateType))"
}
}
}
return predicateString
}
private func getPredicateOperatorString(predicateType: NSCompoundPredicateType) -> String{
switch(predicateType){
case .NotPredicateType: return "!"
case .AndPredicateType: return "&&"
case .OrPredicateType: return "||"
}
}
}
这是用法
let ordersPredicate = NSPredicate()//some predicate passed in
let ordersPredicateFormat = orderPredicate.stringForSubQuery("$x.")
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, \(ordersPredicateFormat)).@count > 0")
对于以后遇到这种情况的任何人,您无需自己构建谓词字符串,只需在子查询字符串中直接使用 predicateFormat
即可。它已经被正确转义,所以使用字符串插值。
let ordersPredicate = NSPredicate()
// Add it to the query with string interpolation
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, \(ordersPredicate.predicateFormat)).@count > 0")
如果您尝试将其作为参数传递,它会再次尝试对字符串进行转义,这可能不起作用。
// Don't do this!
let subQueryPredicate = NSPredicate(format: "SUBQUERY(orders, $x, %@).@count > 0", ordersPredicate.predicateFormat)