Ce que je souhaite mettre en œuvre:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Comment puis-je retourner un objet comme [SomeObject]
si Results
?
Ce que je souhaite mettre en œuvre:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Comment puis-je retourner un objet comme [SomeObject]
si Results
?
Réponses:
Bizarre, la réponse est très simple. Voici comment je le fais:
let array = Array(results) // la fin
Array
construit avec l'itérateur de résultats.
Si vous devez absolument convertir votre Results
en Array
, gardez à l'esprit qu'il y a une surcharge de performances et de mémoire, car Results
c'est paresseux. Mais vous pouvez le faire en une seule ligne, comme results.map { $0 }
dans swift 2.0 (ou map(results) { $0 }
en 1.2).
map { $0 }
reviendra LazyMapRandomAccessCollection
dans Swift 3, donc la réponse @Mazyod est meilleure.
J'ai trouvé une solution. Extension créée sur les résultats.
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
}
}
et en utilisant comme
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++
devrait être remplacé parfor i in 0 ..< count
Avec Swift 4.2, c'est aussi simple qu'une extension:
extension Results {
func toArray() -> [Element] {
return compactMap {
$0
}
}
}
Toutes les informations génériques nécessaires font déjà partie de Results
ce que nous étendons.
C'est une autre façon de convertir Results
en Array avec une extension avec Swift 3 en une seule ligne.
extension Results {
func toArray() -> [T] {
return self.map { $0 }
}
}
Pour Swift 4 et Xcode 9.2
extension Results {
func toArray<T>(type: T.Type) -> [T] {
return flatMap { $0 as? T }
}
}
Avec Xcode 10 flatMap
est obsolète, vous pouvez l'utiliser compactMap
pour le mappage.
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
}
}
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: utiliser des génériques
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
}
ce n'est pas une bonne idée de convertir Results en Array, car Results est paresseux. Mais si vous avez besoin d'essayer ceci:
func toArray<T>(ofType: T.Type) -> [T] {
return flatMap { $0 as? T }
}
mais le meilleur moyen est de transmettre les résultats là où vous en avez besoin. Vous pouvez également convertir les résultats en liste au lieu de tableau.
List(realm.objects(class))
si la première fonction ne fonctionne pas, vous pouvez essayer celle-ci:
var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({$0 as FaceType})
Je ne sais pas s'il existe un moyen efficace de le faire.
Mais vous pouvez le faire en créant un tableau Swift et en l'ajoutant à la boucle.
class func getSomeObject() -> [SomeObject]? {
var someObjects: [SomeObject] = []
let objects = Realm().objects(SomeObject)
for object in objects{
someObjects += [object]
}
return objects.count > 0 ? someObjects : nil
}
Si vous pensez que c'est trop lent. Je vous recommande de faire circuler Results
directement l'objet Realm .
extension Results {
func materialize() -> [Element] {
return Array(self)
}
}