使用Swift过滤Realm对象

6
尝试使用NSPredicate筛选Realm数据库时,我经常会遇到以下错误:

属性'text'不是'type'对象中的链接

我想要筛选Realm数据库,仅显示其中包含特定文本的项目。这是我的尝试:
let realm = try! Realm()
let predicate = NSPredicate(format: "typez.text.filter = 'special'")
let filterThis = realm.objects(Publication).filter(predicate)
print(filterThis)

我模型类的相关部分如下:

class Publication: Object, Mappable {
    dynamic var id: Int = 0
    var typez = List<getType>()
    dynamic var url: String?
}

class getType: Object, Mappable {
    dynamic var text: String = ""
}

你的 Publication 对象实现是什么? - Luca D'Alberti
可以在这里找到相关的编程内容:http://stackoverflow.com/questions/36835805/objectmapper-get-array-of-one-item-within-json - SoundShock
3个回答

11
您提到您的模型类相关部分看起来像这样:

You mentioned that the relevant portions of you model classes look like so:

class Publication: Object, Mappable {
    dynamic var id: Int = 0
    var typez = List<getType>()
    dynamic var url: String?
}

class getType: Object, Mappable {
    dynamic var text: String = ""
}

如果我理解您的意思正确,您想要查找Publication实例,在它们的typez列表中有一个条目,其text等于special。您可以这样表达:

let realm = try! Realm()
let result = realm.objects(Publication).filter("ANY typez.text = 'special'")
print(result)

之前尝试过,但是出现了错误 包含数组属性的键路径必须使用聚合操作 - SoundShock
1
我的错误。您需要包括一个修饰符,如“ANY”,以指定在匹配包含对象时必须匹配List中的多少个元素。我已经更新了答案。 - bdash

1
我不喜欢这里被接受的答案,因为它实际上并没有回答问题......但它帮助了我更多,超出我的预期。现在,我将尽可能使用闭包而不是 NSPredicates。对于这个问题的真正答案应该是 @NSGangster 答案的稍微修改版本。
let realm = try! Realm()
    //Array of publications             
    let realmObjects = realm.objects(Publication)
    //any publication where .text property == special will be filtered. and filter out empty array
    let filterThis = realmObjects.filter({ $0.typez.filter({ $0.text == "special" } != [] ) })
    print(filterThis)

...或者说接近这个。

但我需要的有些不同。我需要一种过滤多个单词字符串中确切单词的方法,使用带有“CONTAINS”的NSPredicate将匹配任何包含子字符串的内容,例如搜索“red”将匹配“fred”。Realm尚不支持“LIKE”或正则表达式,因此使用闭包是我唯一能够使用的东西:

//I was going for a "related terms" result for a dictionary app
let theResults = terms.filter(
    {
        //Looking for other terms in my collection that contained the
        //title of the current term in their definition or more_info strings
        $0.definition.components(separatedBy: " ").contains(term.title) ||
        $0.more_info.components(separatedBy: " ").contains(term.title)
    }
)

我花了很多时间搜索,希望这能帮助其他遇到类似问题的人。


1
Realm从早期的v2.1.2版本开始支持LIKE。请注意,基于闭包进行过滤的方法存在许多缺点,例如性能和内存开销会更大,当Realm发生更改时,结果集合不会自动更新,并且您无法访问通知等功能。 - bdash

-1

我通常不直接使用NSPredicate,而是在过滤器参数中使用内联谓词闭包。

let realm = try! Realm()
                     //Array of publications             
    let realmObjects = realm.objects(Publication)
    //any publication where .text property == special will be filtered. and filter out empty array
    let filterThis = realmObjects.filter({ $0.getType.filter({ $0.text == "special" } != [] ) })
    print(filterThis)

给我以下错误:Cannot invoke 'filter' with an argument list of type '((_) -> _)'。当我将类设置为Equatable时,它说这是多余的一致性。 - SoundShock
这是一个二维数组吗? - NSGangster
因此,该对象(名为Publication)具有诸如ID(Int)、URL(string)和typez(它是getType数组)之类的字段。因此,当您访问Publication.text时,它不存在,因为它在[getType]字段下。如果您想查看Realm数据库的结构,请检查:http://stackoverflow.com/questions/36835805/objectmapper-get-array-of-one-item-within-json - SoundShock
让我们在聊天中继续这个讨论。点击此处进入聊天室 - NSGangster
6
请注意,基于闭包的过滤方式(就像这个答案所展示的那样)有一些缺点:性能和内存开销会更大,结果集合不会在 Realm 发生更改时自动更新,并且您无法获取通知等功能。 - bdash
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接