Cosa voglio implementare:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Come posso restituire l'oggetto come [SomeObject]
invece se Results
?
Cosa voglio implementare:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Come posso restituire l'oggetto come [SomeObject]
invece se Results
?
Risposte:
Strano, la risposta è molto semplice. Ecco come lo faccio:
let array = Array(results) // la fin
Array
costruito con l'iteratore dei risultati.
Se devi assolutamente convertirti Results
in Array
, tieni presente che c'è un sovraccarico di prestazioni e memoria, poiché Results
è pigro. Ma puoi farlo in una riga, come results.map { $0 }
in swift 2.0 (o map(results) { $0 }
in 1.2).
map { $0 }
tornerà LazyMapRandomAccessCollection
in Swift 3, quindi la risposta di @Mazyod è migliore.
Ho trovato una soluzione Estensione creata sui risultati.
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
}
}
e usando come
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject).toArray(SomeObject) as [SomeObject]
return objects.count > 0 ? objects : nil
}
for var i = 0; i < count; i++
dovrebbe essere sostituito confor i in 0 ..< count
Con Swift 4.2 è semplice come un'estensione:
extension Results {
func toArray() -> [Element] {
return compactMap {
$0
}
}
}
Tutte le informazioni generiche necessarie sono già una parte delle Results
quali estendiamo.
Questo è un altro modo di convertire Results
in array con un'estensione con Swift 3 in una sola riga.
extension Results {
func toArray() -> [T] {
return self.map { $0 }
}
}
Per Swift 4 e Xcode 9.2
extension Results {
func toArray<T>(type: T.Type) -> [T] {
return flatMap { $0 as? T }
}
}
Con Xcode 10 flatMap
è deprecato è possibile utilizzare compactMap
per la mappatura.
extension Results {
func toArray<T>(type: T.Type) -> [T] {
return compactMap { $0 as? T }
}
}
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
}
}
uso
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
}
Alternativa: usare generici
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
}
non è una buona idea convertire i risultati in array, perché i risultati sono pigri. Ma se hai bisogno di provare questo:
func toArray<T>(ofType: T.Type) -> [T] {
return flatMap { $0 as? T }
}
ma il modo migliore è passare i risultati ovunque tu abbia bisogno. Inoltre, puoi convertire i risultati in Elenco anziché in Matrice.
List(realm.objects(class))
se la prima funzione non funziona puoi provare questa:
var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({$0 as FaceType})
Non sono sicuro se esiste un modo efficace per farlo.
Ma puoi farlo creando un array Swift e aggiungendolo nel ciclo.
class func getSomeObject() -> [SomeObject]? {
var someObjects: [SomeObject] = []
let objects = Realm().objects(SomeObject)
for object in objects{
someObjects += [object]
}
return objects.count > 0 ? someObjects : nil
}
Se ritieni che sia troppo lento. Ti consiglio di passare Results
direttamente all'oggetto Realm .
extension Results {
func materialize() -> [Element] {
return Array(self)
}
}