Що я хочу реалізувати:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Як я можу повернути об'єкт так, як [SomeObject]
ніби Results
?
Що я хочу реалізувати:
class func getSomeObject() -> [SomeObject]? {
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
}
Як я можу повернути об'єкт так, як [SomeObject]
ніби Results
?
Відповіді:
Дивно, відповідь дуже пряма вперед. Ось як я це роблю:
let array = Array(results) // la fin
Array
побудований з ітератором результатів.
Якщо ви абсолютно повинні перетворити свій Results
на Array
, майте на увазі, що продуктивність і пам'ять накладні, оскільки Results
це лінь. Але ви можете зробити це в одному рядку, як results.map { $0 }
у швидкому 2.0 (або map(results) { $0 }
в 1.2).
map { $0 }
повернеться LazyMapRandomAccessCollection
у Swift 3, тому відповідь @Mazyod краще.
Я знайшов рішення. Створено розширення за результатами.
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
}
for var i = 0; i < count; i++
слід замінити наfor i in 0 ..< count
З Swift 4.2 це так просто, як розширення:
extension Results {
func toArray() -> [Element] {
return compactMap {
$0
}
}
}
Вся необхідна інформація про дженерики - це вже частина, Results
яку ми розширюємо.
Це ще один спосіб перетворення Results
в масив із розширенням із 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 }
}
}
Швидкий 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
}
конвертувати Результати в масив не дуже добре, тому що Результати ліниві. Але якщо вам потрібно спробувати це:
func toArray<T>(ofType: T.Type) -> [T] {
return flatMap { $0 as? T }
}
але кращий спосіб - передавати Результати там, де вам потрібно. Також ви можете конвертувати результати в список замість масиву.
List(realm.objects(class))
якщо перший функціонал не працює, ви можете спробувати цей:
var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({$0 as FaceType})
Я не впевнений, чи є якийсь ефективний спосіб зробити це.
Але ви можете зробити це, створивши масив 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
об'єкта Realm безпосередньо.
extension Results {
func materialize() -> [Element] {
return Array(self)
}
}