使用包含谓词比较两列

时间:2019-08-04 21:08:48

标签: swift core-data nspredicate

我有一个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-Zartist.name = Beyoncé的行将返回true。

如何使用contains谓词比较两列?

1 个答案:

答案 0 :(得分:1)

关于谓词的使用有很多文章。现在是几年前了……a very good article来自NSHipster。

以下是指向Apple文档的链接:

您的问题的答案在于错误消息 LHS和RHS都是关键路径

已经编写了一个简单的谓词:

NSPredicate(格式:KEYPATH 比较器 KEYPATH)

在您的情况下,您应该写一个简单的谓词为:

NSPredicate(格式:KEYPATH 比较器值)


更新

我试图使答案简短些,以鼓励OP对谓词语法的理解...但是也许需要更多解释...

您有一个核心数据实体,我猜它名为Artist,具有以下内容:

  • 类型为String和名称为artistName的属性;
  • 类型为Artist(猜测吗?)和名称为name的关系。

您要检查artistNamename是否都包含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

相关问题