我正在使用 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/