swift - 具有基于递归关系的条件的 NSPredicate - Swift - 核心数据

标签 swift recursion core-data nspredicate recursive-query

我正在使用 Core Data,我有一个基本的文件夹结构。每个项目(文件/文件夹)都是表中的一行。每个项目都有一个 name 属性和一个指向作为其父项目的可选关系。我正在尝试编写一个函数,该函数接受表示路径的字符串数组(例如 ["myFolder", "mySubfolder", "mySubSubfolder", "myFile"])并返回项目在那条路上找到。在英语中,我想问 Core Data 的是“给我所有名称为 myFile、其父级名称为 mySubSubfolder、其祖父级名称为 mySubfolder 的项目,其曾祖 parent 的名字是 myFolder”。用文字描述这个更简单的方法是定义一个名为 item(at: path) 的条件,它对 Core Data 说“给我所有名称为 path.last 的项目> 并且其父项满足 item(at: path.dropLast())”。我内心希望谓词有一个奇特的特性可以使这成为可能,但我对他们来说还很陌生,所以我很难通过谷歌搜索找到答案。

最佳答案

我喜欢尽可能使用强类型方法,而不是在运行时构造和解析格式字符串。

import Foundation

func predicateMatchingPath(_ path: [String]) -> NSPredicate {
    var path = path
    guard let last = path.popLast() else {
        return NSPredicate(value: false)
    }

    var ancestorKeyPath = ""
    let nameSuffix = "name"
    var predicates = [NSPredicate]()

    predicates.append(NSComparisonPredicate(
        leftExpression: NSExpression(forKeyPath: ancestorKeyPath + nameSuffix),
        rightExpression: NSExpression(forConstantValue: last),
        modifier: .direct, type: .equalTo, options: []))

    while let anscestor = path.popLast() {
        ancestorKeyPath.append("parent.")
        predicates.append(NSComparisonPredicate(
            leftExpression: NSExpression(forKeyPath: ancestorKeyPath + nameSuffix),
            rightExpression: NSExpression(forConstantValue: anscestor),
            modifier: .direct, type: .equalTo, options: []))
    }

    // Make sure the most distant ancestor is a root.
    predicates.append(NSComparisonPredicate(
        leftExpression: NSExpression(forKeyPath: ancestorKeyPath + "parent"),
        rightExpression: NSExpression(forConstantValue: nil),
        modifier: .direct, type: .equalTo, options: []))

    return NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
}

print(predicateMatchingPath(["myFolder", "mySubfolder", "mySubSubfolder", "myFile"]))

// Output:
name == "myFile" AND parent.name == "mySubSubfolder" AND parent.parent.name == "mySubfolder" AND parent.parent.parent.name == "myFolder" AND parent.parent.parent.parent == nil

关于swift - 具有基于递归关系的条件的 NSPredicate - Swift - 核心数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54544284/

相关文章:

ios - 将快照字典从 firebase 数据库保存到类对象

ios - Xcode 6 中的 Mapkit 仅在放大时显示日期线以西的叠加层(使用 Swift)

java - 列表列表的递归函数

core-data - 为什么要使用 transient 属性来表示核心数据中的派生只读属性?

ios - 如何在等待核心数据/网络请求时在状态恢复期间显示加载微调器?

core-data - NSSortDescriptor 按核心数据对多关系中的项目数进行排序

C++ 加密库在 Apple Swift 中的使用

swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?

recursion - Racket :识别尾递归?

java - 使用 Runnable 修复 StackOverflowError 递归