我有一个Core Data实体,其中有两列:String类型的artistName
,以及与另一个具有name
列的实体,其类型也为String。
我可以创建一个比较这两列的谓词,如下所示:
NSPredicate(format: "artistName == artist.name")
因此对于包含artistName = Beyoncé
和artist.name = Beyoncé
的行,此谓词返回true。
但是,如果我将其更改为使用contains
,则无法使用:
NSPredicate(format: "artistName contains artist.name")
上面的代码导致此错误:
由于未捕获的异常“ NSInvalidArgumentException”而终止应用程序,原因:“未实现的谓词SQL生成:(artistName包含artist.name)(LHS和RHS均为键路径)”
例如,我想使用contains
创建一个谓词,该谓词对于包含artistName = Beyoncé feat. Jay-Z
和artist.name = Beyoncé
的行将返回true。
如何使用contains
谓词比较两列?
答案 0 :(得分:1)
关于谓词的使用有很多文章。现在是几年前了……a very good article来自NSHipster。
以下是指向Apple文档的链接:
您的问题的答案在于错误消息 LHS和RHS都是关键路径。
您已经编写了一个简单的谓词:
NSPredicate(格式:KEYPATH 比较器 KEYPATH)
在您的情况下,您应该写一个简单的谓词为:
NSPredicate(格式:KEYPATH 比较器值)
我试图使答案简短些,以鼓励OP对谓词语法的理解...但是也许需要更多解释...
您有一个核心数据实体,我猜它名为Artist
,具有以下内容:
String
和名称为artistName
的属性; Artist
(猜测吗?)和名称为name
的关系。您要检查artistName
和name
是否都包含String
“碧昂丝”。
如何进行一次比较呢???在我看来,这是不可能的。
您需要进行两个比较:
artistName
的值是否包含“Beyoncé”; name
的值是否包含“碧昂丝”。那么您如何编写带有两个比较的“比较”谓词?
有很多方法可以做到这一点。
从长远来看,我鼓励您研究NSCompoundPredicate
的功能,因为我相信它将来会为您带来好处。
同时,您可以使用以下语法编写“两次比较”谓词...
let predicate = NSPredicate(format: "(artistName contains 'Beyoncé') AND (name.artistName contains 'Beyoncé')")
或动态/一般...
let keypath1: String = "artistName"
let keypath2: String = "name.artistName"
let value: String = "Beyoncé"
let predicate = NSPredicate(format: "(%K contains %@) AND (%K contains %@)", argumentArray: [keypath1, value, keypath2, value])
注意:
contains[cd]
,以使比较不区分大小写和变音符号,从而处理诸如“é”之类的字符。您现在可能会看到,在您的问题中,第一个==
比较器仅在字面上比较两个隐含字符串值时才起作用。第二个contains
不起作用,因为谓词语法规则期望第二个参数是一个值(LHS是键路径,而RHS是值)。 Swift正在读取第二个contains
,因为“属性artistName
包含与关系name
相关的实体”
Diego Freniche建立了playground来演示谓词的使用...也许值得看一下实际示例? (https://github.com/dfreniche/NSPredicate-Swift)