RealmSwift:将结果转换为 Swift 数组

RealmSwift: Convert Results to Swift Array

我要实现的:

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

    return objects.count > 0 ? objects : nil
}

如果 Results,我如何 return 反对 [SomeObject]

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

但是您可以通过创建一个 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 对象。

我找到了解决办法。在结果上创建了扩展。

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
    }
}

并使用 like

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

    return objects.count > 0 ? objects : nil
}

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

奇怪,答案很直白。这是我的做法:

let array = Array(results) // la fin

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

func toArray<T>(ofType: T.Type) -> [T] {
    return flatMap { [=10=] as? T }
}

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

List(realm.objects(class))

如果第一个功能不起作用,您可以试试这个:

var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({[=12=] as FaceType})

Swift 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
}

这是另一种将 Results 转换为数组的方法,在一行中扩展为 Swift 3

extension Results {
    func toArray() -> [T] {
        return self.map { [=10=] }
    }
}

对于Swift4和Xcode9.2

extension Results {
    func toArray<T>(type: T.Type) -> [T] {
        return flatMap { [=11=] as? T }
    }
}

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

extension Results {
    func toArray<T>(type: T.Type) -> [T] {
        return compactMap { [=12=] as? T }
    }
}
extension Results {
    var array: [Element]? {
        return self.count > 0 ? self.map { [=10=] } : nil
    }
}

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

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

Swift 4 的解决方案,领域 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)

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

extension Results {
    func toArray() -> [Element] {
      return compactMap {
        [=10=]
      }
    }
 }

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

要使用这个:

let someModelResults: Results<SomeModel> = realm.objects(SomeModel.self)
let someModelArray: [SomeModel] = someModelResults.toArray()
extension Results {
    func materialize() -> [Element] {
        return Array(self)
    }
}

使用 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
}