具有多个条件和一个参数的谓词

Posted

技术标签:

【中文标题】具有多个条件和一个参数的谓词【英文标题】:Predicate with many conditions and one argument 【发布时间】:2018-01-03 17:53:33 【问题描述】:

我正在尝试查询联系人领域数据库,但我有一个查询字符串,我需要在谓词中重复它还是有更好的方法?

let contactResults = realm.objects(ContactRealm.self).filter("is_Contact == true AND full_name CONTAINS[c] %@ OR phone_number_one CONTAINS[c] %@ OR phone_number_two CONTAINS[c] %@ OR phone_number_three CONTAINS[c] %@ OR email_address_one CONTAINS[c] %@ OR email_address_two CONTAINS[c] %@", query, query, query, query, query, query).sorted(byKeyPath: "full_name", ascending: true)

这样的查询也被认为是一种不好的做法吗?

更新:正如这里的评论所建议的那样:

let predicateContact = NSPredicate(format: "is_Contact == true")

let fullname = NSPredicate(format: "full_name CONTAINS[c] %@", query)

let phoneNumber = NSPredicate(format: "phone_number_one CONTAINS[c] %@", query)

let phonenumbertwo = NSPredicate(format: "phone_number_one CONTAINS[c] %@", query)

let email = NSPredicate(format: "phone_number_one CONTAINS[c] %@", query)

let secondEmail = NSPredicate(format: "phone_number_one CONTAINS[c] %@", query)

let compoundOr = NSCompoundPredicate(orPredicateWithSubpredicates: [fullname, phoneNumber, phonenumbertwo, email, secondEmail])

let compound = NSCompoundPredicate(type: .and, subpredicates: [predicateContact, compoundOr])

let contactResults = realm.objects(ContactRealm.self).filter(compound).sorted(byKeyPath: "full_name", ascending: true)

【问题讨论】:

当过滤这样的数据时,很容易迷失在谓词上,因此调试非常困难。我绝对建议您使用NSCompoundPredicate 来组合每个单独的谓词。还要避免像is_Contact == true 这样的任何查询,而不是NSPredicate(format: "is_Contact == %@", true) 【参考方案1】:

由于您的谓词看起来相同并且仅显示属性名称的差异,因此我建议创建一个属性名称数组。然后,您可以通过遍历名称为每个名称创建一个NSPredicate

let attributes = ["full_name", "phone_number_one", "phone_number_two", "phone_number_three", "email_address_one", "email_address_two"]
let contactPredicateArray = parameters.map 
    NSPredicate("\($0) CONTAINS[c] %@", query)

let contactPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: contactPredicateArray)
let isContactPredicte = NSPredicate(format: "is_Contact == %@", true)
let predicate = NSCompoundPredicate(type: .and, subpredicates: [isContactPredicte, contactPredicate])

这样,代码更加灵活,因为可以通过修改 attributes 数组轻松地为谓词删除或添加单个属性。它也更具可读性,因为所有属性都在一行中定义,而不是到处定义。

【讨论】:

以上是关于具有多个条件和一个参数的谓词的主要内容,如果未能解决你的问题,请参考以下文章

我在这里使用谓词是不好的做法还是额外的?

用于以任何出现顺序匹配具有多个单词的列中的字符串的 Coredata 谓词

谓词下推

快速,在具有复合谓词的提取结果控制器中找不到实体的键路径

用于获取对象的谓词,其参数包含在特定的 NSSet 中

Dafny 谓词 isBinarySearchTree