NSPredicate具有多个参数和“AND行为”
我有一个函数从一个特定的实体获取符合指定标准的对象:
func fetchWithPredicate(entityName: String, argumentArray: [AnyObject]) -> [NSManagedObject] { let fetchRequest = NSFetchRequest(entityName: entityName) fetchRequest.predicate = NSPredicate(format: "%K == %@", argumentArray: argumentArray) do { return try self.managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject] } catch { let fetchError = error as NSError print(fetchError) return [NSManagedObject]() } }
当我传递一个具有多个aguments(多个属性名称和值)的数组时,似乎会创build一个如下所示的查询:
attributeName1 = value1 OR attributeName2 = value2 OR attributeName3 = value3 OR...
我想要更改这些ORs的AND。
编辑:
问题在于它只是用 “%K ==%@” replace前两个项目 。
所以,我必须创build一个NSCompoundPredicatedynamic地创build一个谓词 。
要dynamic地创build谓词(具有可变数目的expression式),请使用NSCompoundPredicate
,例如
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subPredicates)
其中subPredicates
是一个[NSPredicate]
数组,并且每个子类都是通过提供的参数创build的
NSPredicate(format: "%K == %@", key, value)
像这样(未经testing):
func fetchWithPredicate(entityName: String, argumentArray: [NSObject]) -> [NSManagedObject] { var subPredicates : [NSPredicate] = [] for i in 0.stride(to: argumentArray.count, by: 2) { let key = argumentArray[i] let value = argumentArray[i+1] let subPredicate = NSPredicate(format: "%K == %@", key, value) subPredicates.append(subPredicate) } let fetchRequest = NSFetchRequest(entityName: entityName) fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subPredicates) // ... }
在您的示例中, %K
和%@
格式标记仅由参数数组的前两项replace,其他项将被忽略。
例如,您必须提供所有格式的令牌,以便在string中进行replace
NSPredicate(format: "%K == %@ AND %K == %@", argumentArray:["key1", "value1", "key2", "value2"])
你可以使用复合谓词。 我会给你Objective-C的语法,我将把这个翻译作为一个练习,留给Swift …
如果您的键和值在字典中:
NSDictionary *conds = @{ @"key1": @"value1", @"key2", @"value2" }; NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:conds.allKeys.length]; for (NSString *key in conds.allKeys) { [predicates addObject:[NSPredicate predicateWithFormat:@"%K == %@", key, conds[key]]]; } NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
Swift 3
我find了最简单的方法。
var predicate = NSPredicate(format: "key1 = %@ AND key2 = %@", value1, value2)