Realm Swift - 按 ID 查找

Posted

技术标签:

【中文标题】Realm Swift - 按 ID 查找【英文标题】:Realm Swift - Find by IDs 【发布时间】:2020-04-10 17:02:06 【问题描述】:

我需要使用 id 列表查询 Realm 对象,id 是对象的主键。我尝试了以下方法:

// Query a list of Dogs by their _ids
let doggoIds = ["1", "2", "3", "1", "2"]
realm.objects(Dog.self).filter("_id IN %@", doggoIds)
// Result: [Dog1, Dog2, Dog3]

id 列表包含重复项,但如您所见,结果是唯一的 Dog 对象列表。

我想知道是否有人可以想出一种不同的方式来编写此查询,以便我们从包含重复项的 id 列表中获得一个不错的 Results<Dog> 集合。谢谢!

【问题讨论】:

为什么要复制?请记住,结果仅包含唯一对象 【参考方案1】:

领域结果包含唯一的对象,因此最简单的解决方案是查询每只狗并将结果添加到数组中。 CompactMap 在这方面做得很好,因为它过滤掉了 nil。

let listOfDogsToFind = ["Fido", "Dino", "Sport", "Fido", "Cupid"]

let dogArray = listOfDogsToFind.compactMap  dogName -> DogClass? in
    if let result = realm.objects(DogClass.self).filter("dog_name == %@", dogName).first 
        return result
    
    return nil


for dog in dogArray 
    print("dog name: \(dog.dog_name)")

假设丘比特不存在,这是输出

dog name: Fido
dog name: Dino
dog name: Sport
dog name: Fido

【讨论】:

非常感谢@Jay,compactMap 是一个很好的建议,但是由于我是按 ID 而不是按名称搜索,object(ofType:, forPrimaryKey:) 在这里可能更合适。 @EmilienHuet 这是一种设计模式 - 您可以使用 dog_name、ID、shoe_size 或任何适用的字段。【参考方案2】:

Realm.objects().filter 返回“实时”托管对象的列表。它不会返回重复项,因为只有一个对象与主键匹配。为了完成您想要的,您需要为每个对象创建一个“非托管”副本,并让这些非托管对象组成您自己的数组将每个返回的实例映射到您自己的数组中。

啊啦:

let doggoIds = [1, 2, 3, 1, 2]
    for managedMuttId in doggoIds 
        if let managedMutt = realm.object(ofType: Dog.self, forPrimaryKey: managedMuttId) 
            // unmanaged.append(Dog(value: managedMutt))
            duplicateList.append(managedMutt)
        
    

【讨论】:

@EmilienHuet 这是一个很好的答案,但文字不正确。 Swift 数组可以保存重复的对象,因此没有理由为 Realm 对象创建非托管版本,因为它们将存储在数组中。 我现在可以看到 OP 如何要求 Results<Dog> 类型的结果,所以这不能回答他的问题。 非常感谢!我想要一个Results<Dog> 集合的原因是我可以利用领域集合通知,并在我的NSTableView 中过滤/排序集合。希望对这些东西使用数组不会对性能产生太大影响。

以上是关于Realm Swift - 按 ID 查找的主要内容,如果未能解决你的问题,请参考以下文章

Realm Cocoa:通过 PK 查找多个对象

使用 Swift 2 编程从 Persistent ID 中查找歌曲

UITableView 使用 Realm 和 Swift 具有多个按字母顺序排列的部分,多个标签与相同的数据连接

使用Swift 2编程从持久ID中查找歌曲

Swift + Realm:如何从 collection.find 的范围内更改外部变量

按 id 查找布局