FetchedResultsController使用谓词排除包含在集合中的结果

时间:2018-07-21 19:36:49

标签: swift core-data swift4

我正在尝试过滤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

}

2 个答案:

答案 0 :(得分:0)

使用IN代替CONTAINS

NOT (engineDesignation IN %@)

更新

既然您想排除所有字母(树字母除外),为什么不把谓词转为包括而不是排除呢?

engineDesignation BEGINSWITH ‘A’ OR
engineDesignation BEGINSWITH ‘B’ OR
engineDesignation BEGINSWITH ‘C’

答案 1 :(得分:0)

感谢此处的帖子: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中的每个项目创建一个单独的谓词。我什至可以通过编程方式即时更改它。我真的希望这对某人有帮助,因为没有中心位置可以提出这些技巧。当我收集到足够多的邮件时,我将做一篇主帖。