RealmSwift: Convert Results to Swift Array

IosSwiftRealm

Ios Problem Overview


What I want to implement:

class func getSomeObject() -> [SomeObject]? {
    let objects = Realm().objects(SomeObject)
    
    return objects.count > 0 ? objects : nil
}

How can I return object as [SomeObject] instead if Results?

Ios Solutions


Solution 1 - Ios

Weird, the answer is very straightforward. Here is how I do it:

let array = Array(results) // la fin

Solution 2 - Ios

If you absolutely must convert your Results to Array, keep in mind there's a performance and memory overhead, since Results is lazy. But you can do it in one line, as results.map { $0 } in swift 2.0 (or map(results) { $0 } in 1.2).

Solution 3 - Ios

I found a solution. Created extension on 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
    }
}

and using like

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

    return objects.count > 0 ? objects : nil
}

Solution 4 - Ios

With Swift 4.2 it's as simple as an extension:

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

All the needed generics information is already a part of Results which we extend.

To use this:

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

Solution 5 - Ios

This an another way of converting Results into Array with an extension with Swift 3 in a single line.

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

For Swift 4 and Xcode 9.2

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

With Xcode 10 flatMap is deprecated you can use compactMap for mapping.

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

Solution 6 - Ios

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

Usage

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
}

Alternative : Using generics

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
}

Solution 7 - Ios

it's not a good idea to convert Results to Array, because Results is lazy. But if you need try this:

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

but better way is to pass Results wherever you need. Also you can convert Results to List instead of Array.

List(realm.objects(class))

if the first func is not working you can try this one:

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

Solution 8 - Ios

Solution for Swift 4, Realm 3

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

Now converting can be done as below

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

Solution 9 - Ios

I'm not sure, if there is any efficient way to do this.

But you can do it by create a Swift array and append it in the loop.

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

If you feel it's too slow. I recommend you to pass around Realm Results object directly.

Solution 10 - Ios

extension Results {
    var array: [Element]? {
        return self.count > 0 ? self.map { $0 } : nil
    }
}

So, you can use like:

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

Solution 11 - Ios

extension Results {
    func materialize() -> [Element] {
        return Array(self)
    }
}

Solution 12 - Ios

Using Swift 5 and RealmSwift v10.20.0

This methods works:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSahil KapoorView Question on Stackoverflow
Solution 1 - IosMazyodView Answer on Stackoverflow
Solution 2 - IossegiddinsView Answer on Stackoverflow
Solution 3 - IosSahil KapoorView Answer on Stackoverflow
Solution 4 - IosNeverwinterMoonView Answer on Stackoverflow
Solution 5 - IosabdullahselekView Answer on Stackoverflow
Solution 6 - IosJaseem AbbasView Answer on Stackoverflow
Solution 7 - IosNosov PavelView Answer on Stackoverflow
Solution 8 - IosVinayakView Answer on Stackoverflow
Solution 9 - IosnRewikView Answer on Stackoverflow
Solution 10 - IoslindaaakView Answer on Stackoverflow
Solution 11 - IosDesmond HumeView Answer on Stackoverflow
Solution 12 - IosMiguel GallegoView Answer on Stackoverflow