使用包含谓词比较两列
Compare two columns using the contains predicate
我有一个包含两列的核心数据实体:artistName
,字符串类型,以及与另一个实体的关系,该实体有一个列 name
,也是字符串类型。
我可以创建一个谓词来比较这两列,如下所示:
NSPredicate(format: "artistName == artist.name")
因此对于 artistName = Beyoncé
和 artist.name = Beyoncé
的行,此谓词 return 为真。
但是,如果我将其更改为使用 contains
,它不起作用:
NSPredicate(format: "artistName contains artist.name")
以上代码导致此错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (artistName CONTAINS artist.name) (LHS and RHS both keypaths)'
我想使用 contains
创建一个谓词,例如 return 对具有 artistName = Beyoncé feat. Jay-Z
和 artist.name = Beyoncé
的行为真。
如何使用 contains
谓词比较两列?
有很多关于谓词使用的文章。虽然现在已经是几年前了...a very good article 来自 NSHipster。
以下是 Apple 文档的一些链接:
您的问题的答案在于错误消息 LHS 和 RHS 都是键路径。
您已经编写了一个简单的谓词:
NSPredicate(格式:KEYPATH 比较器 KEYPATH)
在你的例子中,你应该写一个简单的谓词:
NSPredicate(格式:KEYPATH 比较器 VALUE)
更新
我试图让我的回答简短,以鼓励 OP 加深对谓词语法的理解……但是也许需要更多解释……
你有一个核心数据实体,我猜它被命名为 Artist
,具有以下内容:
- 类型
String
和名称 artistName
的属性;
- 类型
Artist
的关系(猜测?)和名称 name
。
您想检查 artistName
和 name
是否都包含 String
"Beyoncé".
你怎么能通过一次比较就做到这一点???以我愚见,不可能。
你需要两个比较:
- 检查属性
artistName
的值是否包含 "Beyoncé";
- 检查关系
name
的值是否包含 "Beyoncé".
那么如何编写一个带有两个比较的 "compare" 谓词?
有多种方法可以做到这一点。
从长远来看,我鼓励您研究 NSCompoundPredicate
的力量,因为我相信它会在未来为您服务。
同时,您可以使用以下语法编写 "two comparison" 谓词...
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
不起作用,因为谓词语法规则期望第二个参数是一个值(左轴是键路径,右轴是值)。 Swift 将第二个 contains
读为 "attribute artistName
contains the entity associated with the relationship name
"
Diego Freniche 构建了一个 playground 来演示谓词的使用...也许值得查看实际示例?
(https://github.com/dfreniche/NSPredicate-Swift)
我有一个包含两列的核心数据实体:artistName
,字符串类型,以及与另一个实体的关系,该实体有一个列 name
,也是字符串类型。
我可以创建一个谓词来比较这两列,如下所示:
NSPredicate(format: "artistName == artist.name")
因此对于 artistName = Beyoncé
和 artist.name = Beyoncé
的行,此谓词 return 为真。
但是,如果我将其更改为使用 contains
,它不起作用:
NSPredicate(format: "artistName contains artist.name")
以上代码导致此错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (artistName CONTAINS artist.name) (LHS and RHS both keypaths)'
我想使用 contains
创建一个谓词,例如 return 对具有 artistName = Beyoncé feat. Jay-Z
和 artist.name = Beyoncé
的行为真。
如何使用 contains
谓词比较两列?
有很多关于谓词使用的文章。虽然现在已经是几年前了...a very good article 来自 NSHipster。
以下是 Apple 文档的一些链接:
您的问题的答案在于错误消息 LHS 和 RHS 都是键路径。
您已经编写了一个简单的谓词:
NSPredicate(格式:KEYPATH 比较器 KEYPATH)
在你的例子中,你应该写一个简单的谓词:
NSPredicate(格式:KEYPATH 比较器 VALUE)
更新
我试图让我的回答简短,以鼓励 OP 加深对谓词语法的理解……但是也许需要更多解释……
你有一个核心数据实体,我猜它被命名为 Artist
,具有以下内容:
- 类型
String
和名称artistName
的属性; - 类型
Artist
的关系(猜测?)和名称name
。
您想检查 artistName
和 name
是否都包含 String
"Beyoncé".
你怎么能通过一次比较就做到这一点???以我愚见,不可能。
你需要两个比较:
- 检查属性
artistName
的值是否包含 "Beyoncé"; - 检查关系
name
的值是否包含 "Beyoncé".
那么如何编写一个带有两个比较的 "compare" 谓词?
有多种方法可以做到这一点。
从长远来看,我鼓励您研究 NSCompoundPredicate
的力量,因为我相信它会在未来为您服务。
同时,您可以使用以下语法编写 "two comparison" 谓词...
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
不起作用,因为谓词语法规则期望第二个参数是一个值(左轴是键路径,右轴是值)。 Swift 将第二个 contains
读为 "attribute artistName
contains the entity associated with the relationship name
"
Diego Freniche 构建了一个 playground 来演示谓词的使用...也许值得查看实际示例? (https://github.com/dfreniche/NSPredicate-Swift)