swift - FetchedResultsController 使用谓词排除集合中包含的结果
问题描述
我正在尝试过滤 FetchedResultsController 中的项目以过滤掉一组项目。这些是引擎,其中有特定的字母名称,后跟数字。名称中可能的字母范围是从“A”到“O”。我希望能够根据另一个条件过滤掉名称从“D”到“O”的引擎。
我设置了一个常量“highPowerEngines”,它是一个包含这些字母的集合。由于该名称仅包含一个字母,因此我想排除任何包含 highPowerEngines 中任何字母的名称。到目前为止,这是我的代码,我正在处理的谓词包含在 FIXME 之后:
func configureFetchedResultsController() {
let context = databaseController.getContext()
let enginesFetchRequest = NSFetchRequest<Engine>(entityName: CoreData.engine)
let highPowerEngines: Set = ["D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"]
var predicate = NSPredicate()
if currentStage == 1 && stages! == 1 {
predicate = NSPredicate(format: "engineType == %@", EngineType.singleStage.rawValue)
} else if currentStage < stages! {
predicate = NSPredicate(format: "engineType == %@", EngineType.boosterStage.rawValue)
} else {
predicate = NSPredicate(format: "engineType == %@", EngineType.upperStage.rawValue)
}
var predicateArray:[NSPredicate] = [
predicate
]
// FIXME: Sort out highPowerEngines
if !dPlusEngineIAP {
if currentStage == 1 && stages! == 1 {
predicate = NSPredicate(format: "NOT engineDesignation CONTAINS %@", highPowerEngines)
predicateArray.append(predicate)
}
}
let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
enginesFetchRequest.predicate = compoundPredicate
let primarySortDescriptor = NSSortDescriptor(key: CoreData.isMadeByName, ascending: true)
let secondarySortDescriptor = NSSortDescriptor(key: CoreData.engineDesignation, ascending: true)
enginesFetchRequest.sortDescriptors = [primarySortDescriptor, secondarySortDescriptor]
self.fetchedResultsController = NSFetchedResultsController<Engine>(
fetchRequest: enginesFetchRequest,
managedObjectContext: context,
sectionNameKeyPath: CoreData.isMadeByName,
cacheName: nil)
self.fetchedResultsController.delegate = self
}
解决方案
感谢这里的帖子:CoreData Predicate get every sentence that contains any word in array ,我终于能够解决我的问题。我当前的工作代码在这里:
func configureFetchedResultsController() {
let context = databaseController.getContext()
let enginesFetchRequest = NSFetchRequest<Engine>(entityName: CoreData.engine)
let lowPowerEngines = ["A", "B", "C"]
var predicate = NSPredicate()
if currentStage == 1 && stages! == 1 {
predicate = NSPredicate(format: "engineType == %@", EngineType.singleStage.rawValue)
} else if currentStage < stages! {
predicate = NSPredicate(format: "engineType == %@", EngineType.boosterStage.rawValue)
} else {
predicate = NSPredicate(format: "engineType == %@", EngineType.upperStage.rawValue)
}
var predicateArray:[NSPredicate] = [
predicate
]
if !dPlusEngineIAP {
let predicates = lowPowerEngines.map {
NSPredicate(format: "engineDesignation CONTAINS %@", $0)
}
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
predicateArray.append(predicate)
}
let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
enginesFetchRequest.predicate = compoundPredicate
let primarySortDescriptor = NSSortDescriptor(key: CoreData.isMadeByName, ascending: true)
let secondarySortDescriptor = NSSortDescriptor(key: CoreData.engineDesignation, ascending: true)
enginesFetchRequest.sortDescriptors = [primarySortDescriptor, secondarySortDescriptor]
self.fetchedResultsController = NSFetchedResultsController<Engine>(
fetchRequest: enginesFetchRequest,
managedObjectContext: context,
sectionNameKeyPath: CoreData.isMadeByName,
cacheName: nil)
self.fetchedResultsController.delegate = self
}
处理数组中每个项目的解决方案是使用 map 函数创建一个复合谓词。然后将复合谓词添加到 fetchedResultsController。这让我可以比较引擎,看看它是否在 lowPowerEngines 中。Map 为 lowPowerEngines 中的每个项目创建一个单独的谓词。我什至可以即时以编程方式更改它。我真的希望这对某人有所帮助,因为没有中心位置可以提出这些技巧。当我收集到足够的它们时,我会做一个主帖。
推荐阅读
- c++ - 函数中类实例的生命周期
- javascript - 在 React + Apollo/GraphQL 中使用 useLazyQuery 时出现无限循环?
- python - 为什么这个函数有一个 TypeError?
- cypress - 断言具有未知文件名的下载文件
- reactjs - 如何停止受控输入的光标跳跃
- react-native - 我应该取消订阅这个听众吗?
- svelte - 页面捆绑不会通过 goto() 在路由上发送 css。仅提供 JS 捆绑包/块。仅在产品上发生
- deep-learning - 如何在网页浏览器上实现 labelImg 功能
- haskell - 如何判断包装在 SomeException 中的异常是否是类的实例?
- java - 设置 Java 数据库