首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将嵌套的条件If语句转换为复杂的NSCompoundPredicate

将嵌套的条件If语句转换为复杂的NSCompoundPredicate
EN

Stack Overflow用户
提问于 2020-06-12 08:36:04
回答 2查看 42关注 0票数 1

我正在使用SwiftUI为一个旧的基于iOS的项目编写一个macOS目标。Is是一个核心数据驱动的应用程序,对于macOS目标,我已经成功地使用动态@FetchRequest实现了泛型列表,主要是像Paul Hudson在他的blog中描述的那样。

我主要是通过遵循苹果的SwiftUI Tutorials并复制提供的示例代码来构建目标的。

之前使用的条件if语句根据3个UI控件主动过滤每个SwiftUI List

代码语言:javascript
复制
// PART 1
    if (!self.appData.showFavouritesOnly
        || fetchedEvent.isFavourite)
// PART 2
    && (self.searchText.count == 0
        || (fetchedEvent.eventName?.contains(self.searchText) == true))
// PART 3
    && (self.filter == .all
        || self.filter.name == fetchedEvent.eventCategory
        || (self.filter.category == .featured && fetchedEvent.isFeatured)) {

现在我有了一个使用谓词的通用@FetchRequest,我想把这个条件if语句转换成一个NSCompoundPredicate

我将包含整个初始化器,这样您就可以看到动态@FetchRequest是如何构建的,但它是我需要帮助的谓词...

代码语言:javascript
复制
init(sortDescriptors: [NSSortDescriptor],
     searchKey: String,
     searchValue: String?,
     showFavourites: Bool,
     filterKey: String,
     filter: FilterType,
     @ViewBuilder content: @escaping (T) -> Content) {

    let entity = T.entity
    let predicateTrue = NSPredicate(value: true)
// PART 1
    let predicateFavourite = showFavourites == false ? predicateTrue : NSPredicate(format: "isFavourite == TRUE")
// PART 2
    let predicateSearch = searchValue?.count == 0 ? predicateTrue : NSPredicate(format: "%K CONTAINS[cd] %@", searchKey, searchValue!)

    // The initialiser works perfectly down to this point...then...
// PART 3
    let predicateFilterName = filter == .all ? predicateTrue : NSPredicate(format: "%K == %@", filterKey, filter.name as CVarArg)
    let predicateFilterFeature = filter.category == .featured ? NSPredicate(format: "isFeatured == TRUE") : predicateTrue

    let predicateOr = NSCompoundPredicate(orPredicateWithSubpredicates: [predicateFilterName, predicateFilterFeature])
    let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateFavourite, predicateSearch, predicateOr])

    fetchRequest =
        FetchRequest<T>(entity: entity,
                        sortDescriptors: sortDescriptors,
                        predicate: predicate)

    self.content = content
}

第3部分中包含的代码可以部分工作。在FilterType.allFilterType.featured之间切换会产生预期的变化,但是我很难为“其他”情况编写谓词,当选择了另一个类别时-也就是说-不是特征,而是.lakes.rivers.mountains

为了完整性,我还包含了枚举Category和结构FilterType...

代码语言:javascript
复制
enum Category: String, CaseIterable, Codable, Hashable {

    case featured = "Featured"
    case lakes = "Lakes"
    case rivers = "Rivers"
    case mountains = "Mountains"
}

struct FilterType: CaseIterable, Hashable, Identifiable {

    var name: String
    var category: Category?

    init(_ category: Category) {
        self.name = category.rawValue
        self.category = category
    }

    init(name: String) {
        self.name = name
        self.category = nil
    }

    static var all = FilterType(name: "All")

    static var allCases: [FilterType] {
        return [.all] + Category.allCases.map(FilterType.init)
    }

    var id: FilterType {
        return self
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-12 16:09:45

我认为问题出在这里:

代码语言:javascript
复制
 let predicateFilterFeature = filter.category == .featured ? NSPredicate(format: "isFeatured == TRUE") : predicateTrue

如果筛选器为.lakes等,则此子谓词将为TRUE,当使用predicateFilterName的ORed覆盖它时,此子谓词将为TRUE。尝试返回FALSE:

代码语言:javascript
复制
 let predicateFilterFeature = filter.category == .featured ? NSPredicate(format: "isFeatured == TRUE") : predicateFalse
票数 1
EN

Stack Overflow用户

发布于 2020-06-12 19:59:34

我的答案是欺骗性的,因为它是我在尝试以不同的方式考虑谓词的构造后偶然发现的一个被破解的解决方案。(对于理解我编写的谓词的语法这一实际问题,本文并没有进行任何仔细的思考。)

所以这个响应没有回答我最初的问题--这个问题已经由@pbasdf回答了--尽管这个响应得到了相同的结果。

所以也许有替代的解决方案?!?

代码语言:javascript
复制
let predicateTrue = NSPredicate(value: true)

let predicateFavourite = showFavourites == false ? predicateTrue : NSPredicate(format: "isFavourite == TRUE")

let predicateSearch = searchValue?.count == 0 ? predicateTrue : NSPredicate(format: "%K CONTAINS[cd] %@", searchKey, searchValue!)

let predicateFilterFeatured = NSPredicate(format: "isFeatured == TRUE")
let predicateFilterName = NSPredicate(format: "%K == %@", filterKey, filter.name as CVarArg)
let predicateFilterCategory = filter.category == .featured ? predicateFilterFeatured : predicateFilterName

let predicateFilter = filter == .all ? predicateTrue : predicateFilterCategory

let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateFavourite, predicateSearch, predicateFilter])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62335708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档