RealmSwift:将结果转换为 Swift 数组

Posted

技术标签:

【中文标题】RealmSwift:将结果转换为 Swift 数组【英文标题】:RealmSwift: Convert Results to Swift Array 【发布时间】:2015-09-14 23:47:44 【问题描述】:

我想要实现的:

class func getSomeObject() -> [SomeObject]? 
    let objects = Realm().objects(SomeObject)

    return objects.count > 0 ? objects : nil

如果Results,我怎样才能将对象返回为[SomeObject]

【问题讨论】:

【参考方案1】:

我找到了解决方案。在结果上创建了扩展。

extension Results 
    func toArray<T>(ofType: T.Type) -> [T] 
        var array = [T]()
        for i in 0 ..< count 
            if let result = self[i] as? T 
                array.append(result)
            
        

        return array
    

并使用类似

class func getSomeObject() -> [SomeObject]? 
    let objects = Realm().objects(SomeObject).toArray(SomeObject) as [SomeObject]

    return objects.count > 0 ? objects : nil

【讨论】:

for var i = 0; i &lt; count; i++ 应替换为 for i in 0 ..&lt; count 上面写扩展的方式很混乱:extension Results var array: [Element] return self.map $0 【参考方案2】:

我不确定,是否有任何有效的方法可以做到这一点。

但您可以通过创建一个 Swift 数组并将其附加到循环中来实现。

class func getSomeObject() -> [SomeObject]? 
    var someObjects: [SomeObject] = []
    let objects = Realm().objects(SomeObject)
    for object in objects
        someObjects += [object]
    
    return objects.count > 0 ? someObjects : nil

如果你觉得它太慢了。我建议你直接传递 Realm Results 对象。

【讨论】:

我只是通过在 Resules 上创建一个扩展来做类似的事情。我已经发布了代码作为答案。谢谢:) 是的。我也会这样做。【参考方案3】:

如果您绝对必须将Results 转换为Array,请记住存在性能和内存开销,因为Results 是惰性的。但是您可以在一行中完成,如 swift 2.0 中的 results.map $0 (或 1.2 中的 map(results) $0 )。

【讨论】:

Realm 的哪个版本? 如果您不想将 Realm 的依赖泄露给项目中的太多类,这种转换不是必须的吗? map $0 将在 Swift 3 中返回 LazyMapRandomAccessCollection,所以 @Mazyod 的答案更好。 @MarcinKuptel 是的,这正是我发现的问题。我已经能够通过创建一个符合协议的结构来抽象出领域模型,我在代码库的签名中定义了这个协议抽象。但是有时我需要转换为数组,有没有办法可以对我的抽象协议进行惰性集合,以便它只在访问时转换为结构?【参考方案4】:

奇怪,答案很简单。这是我的做法:

let array = Array(results) // la fin

【讨论】:

不是返回一个NSArray吗? @thesummersign 领域最近发生了很大的变化,但有一点是肯定的:上面的代码返回一个由结果迭代器构造的 Swift Array 它返回实体的 nil vars(初始) 我同意@NikKov,它似乎返回了实体的 nil vars ;( @Jon 你怎么看他们是零?似乎因为它们很懒惰,当您看到它们在调试点停止时,它们看起来是空的,但是如果您将它们打印出来,它会访问它们并显示正确的值(对我来说)。【参考方案5】:

将结果转换为数组不是一个好主意,因为结果是惰性的。但如果你需要试试这个:

func toArray<T>(ofType: T.Type) -> [T] 
    return flatMap  $0 as? T 

但更好的方法是将结果传递到您需要的任何地方。您也可以将结果转换为列表而不是数组。

List(realm.objects(class))

如果第一个函数不起作用,你可以试试这个:

var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map($0 as FaceType)

【讨论】:

RealmSwift 更新到 3.4.0 后,List 不再接受参数。在这种情况下如何将数组转换为 List?有什么想法吗? @NishuPriya 在这里让 myList = List() myList.append(objectsIn: realm.objects(Person.self))【参考方案6】:

斯威夫特 3

extension Results 
    func toArray<T>(ofType: T.Type) -> [T] 
        var array = [T]()
        for i in 0 ..< count 
            if let result = self[i] as? T 
                array.append(result)
            
        

        return array
    

用法

class func getSomeObject() -> [SomeObject]? 
   let defaultRealm = try! Realm()
    let objects = defaultRealm.objects(SomeObject.self).toArray(ofType : SomeObject.self) as [SomeObject]

    return objects.count > 0 ? objects : nil

替代方案:使用泛型

class func getSomeObject() -> [T]? 
        let objects = Realm().objects(T.self as! Object.Type).toArray(ofType : T.self) as [T]

        return objects.count > 0 ? objects : nil

【讨论】:

【参考方案7】:

这是另一种将 Results 转换为 Array 的方法,其扩展名为 Swift 3

extension Results 
    func toArray() -> [T] 
        return self.map  $0 
    

适用于 Swift 4 和 Xcode 9.2

extension Results 
    func toArray<T>(type: T.Type) -> [T] 
        return flatMap  $0 as? T 
    

使用 Xcode 10 flatMap 已弃用,您可以使用 compactMap 进行映射。

extension Results 
    func toArray<T>(type: T.Type) -> [T] 
        return compactMap  $0 as? T 
    

【讨论】:

当我在 9.2 版本的 XCode 中使用此代码时,它向我展示了使用未声明的类型 'T' 更新了我的答案,你可以查看一下。 对于 Xcode 10 及更高版本,您可以使用 compactMap 而不是 flatMap 来避免警告。 嗨!你能说一下如何调用 toArray 函数吗?我需要将 Results 转换为 [Int]。【参考方案8】:
extension Results 
    var array: [Element]? 
        return self.count > 0 ? self.map  $0  : nil
    

所以,你可以像这样使用:

Realm().objects(SomeClass.self).filter("someKey ENDSWITH %@", "sth").array

【讨论】:

【参考方案9】:

Swift 4、Realm 3 的解决方案

extension Results 
    func toArray<T>(ofType: T.Type) -> [T] 
        let array = Array(self) as! [T]
        return array
    

现在可以如下进行转换

let array = Realm().objects(SomeClass).toArray(ofType: SomeClass.self)

【讨论】:

【参考方案10】:

使用 Swift 4.2,它就像一个扩展一样简单:

extension Results 
    func toArray() -> [Element] 
      return compactMap 
        $0
      
    
 

所有需要的泛型信息已经是我们扩展的Results 的一部分。

要使用这个:

let someModelResults: Results<SomeModel> = realm.objects(SomeModel.self)
let someModelArray: [SomeModel] = someModelResults.toArray()

【讨论】:

你是如何使用这个功能的? realm.objects(SomeModel.self).toArray()【参考方案11】:
extension Results 
    func materialize() -> [Element] 
        return Array(self)
    

【讨论】:

【参考方案12】:

使用 Swift 5 和 RealmSwift v10.20.0

此方法有效:

private func convertToArray<R>(results: Results<R>) -> [R] where R: Object 
    var arrayOfResults: [R] = []
    for result in results 
        arrayOfResults.append(result)
    
    return arrayOfResults

【讨论】:

以上是关于RealmSwift:将结果转换为 Swift 数组的主要内容,如果未能解决你的问题,请参考以下文章

我可以将.png数据转换为Swift中的Int吗?

Realm Swift 使用部分更新 collectionView

Swift 项目:ReactiveSwift+MVVM+RealmSwift+Alamofire+OM

RealmSwift 限制和获取最后 30 条记录到 tableview

Swift 3 ObjectMapper - 将 URLSession 结果转换为 Map 对象失败

Swift Realm模拟器权限被拒绝