RealmSwift: 将结果转换为 Swift 数组

我想实现的是:

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


return objects.count > 0 ? objects : nil
}

如果返回的对象是 Results,那么如何返回 [SomeObject]

87522 次浏览

我找到了一个解决方案,在 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
}
}

并且使用类似

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


return objects.count > 0 ? objects : nil
}

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

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

如果你觉得它太慢。我建议你通过领域 Results对象直接。

如果您必须将 Results转换为 Array,请记住,由于 Results是惰性的,因此存在性能和内存开销。但是你可以在一行中完成,就像在 Swift 2.0中的 results.map { $0 }(或者在1.2中的 map(results) { $0 })。

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

let array = Array(results) // la fin

将 Results 转换为 Array 并不是一个好主意,因为 Results 是惰性的:

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

但是更好的方法是在任何需要的地方传递 Results。

List(realm.objects(class))

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

var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({$0 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转换为 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 }
}
}
extension Results {
var array: [Element]? {
return self.count > 0 ? self.map { $0 } : nil
}
}

所以,你可以这样使用:

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

快手四号,领域三号解决方案

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 {
$0
}
}
}


所有需要的泛型信息已经是我们扩展的 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
}