RealmSwift:将结果转换为 Swift 数组
Posted
技术标签:
【中文标题】RealmSwift:将结果转换为 Swift 数组【英文标题】:RealmSwift: Convert Results to Swift Array 【发布时间】:2015-09-14 23:47:44 【问题描述】:我想要实现的:
class func getSomeObject() -> [SomeObject]?
let objects = Realm().objects(SomeObject)
return objects.count > 0 ? objects : nil
如果Results
,我怎样才能将对象返回为[SomeObject]
?
【问题讨论】:
【参考方案1】:我找到了解决方案。在结果上创建了扩展。
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
上面写扩展的方式很混乱:extension Results var array: [Element] return self.map $0 【参考方案2】:
我不确定,是否有任何有效的方法可以做到这一点。
但您可以通过创建一个 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
如果你觉得它太慢了。我建议你直接传递 Realm Results
对象。
【讨论】:
我只是通过在 Resules 上创建一个扩展来做类似的事情。我已经发布了代码作为答案。谢谢:) 是的。我也会这样做。【参考方案3】:如果您绝对必须将Results
转换为Array
,请记住存在性能和内存开销,因为Results
是惰性的。但是您可以在一行中完成,如 swift 2.0 中的 results.map $0
(或 1.2 中的 map(results) $0
)。
【讨论】:
Realm 的哪个版本? 如果您不想将 Realm 的依赖泄露给项目中的太多类,这种转换不是必须的吗?map $0
将在 Swift 3 中返回 LazyMapRandomAccessCollection
,所以 @Mazyod 的答案更好。
@MarcinKuptel 是的,这正是我发现的问题。我已经能够通过创建一个符合协议的结构来抽象出领域模型,我在代码库的签名中定义了这个协议抽象。但是有时我需要转换为数组,有没有办法可以对我的抽象协议进行惰性集合,以便它只在访问时转换为结构?【参考方案4】:
奇怪,答案很简单。这是我的做法:
let array = Array(results) // la fin
【讨论】:
不是返回一个NSArray吗? @thesummersign 领域最近发生了很大的变化,但有一点是肯定的:上面的代码返回一个由结果迭代器构造的 SwiftArray
。
它返回实体的 nil vars(初始)
我同意@NikKov,它似乎返回了实体的 nil vars ;(
@Jon 你怎么看他们是零?似乎因为它们很懒惰,当您看到它们在调试点停止时,它们看起来是空的,但是如果您将它们打印出来,它会访问它们并显示正确的值(对我来说)。【参考方案5】:
将结果转换为数组不是一个好主意,因为结果是惰性的。但如果你需要试试这个:
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)
【讨论】:
RealmSwift 更新到 3.4.0 后,List 不再接受参数。在这种情况下如何将数组转换为 List?有什么想法吗? @NishuPriya 在这里让 myList = List斯威夫特 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
【讨论】:
【参考方案7】:这是另一种将 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
【讨论】:
当我在 9.2 版本的 XCode 中使用此代码时,它向我展示了使用未声明的类型 'T' 更新了我的答案,你可以查看一下。 对于 Xcode 10 及更高版本,您可以使用 compactMap 而不是 flatMap 来避免警告。 嗨!你能说一下如何调用 toArray 函数吗?我需要将 Resultsextension Results
var array: [Element]?
return self.count > 0 ? self.map $0 : nil
所以,你可以像这样使用:
Realm().objects(SomeClass.self).filter("someKey ENDSWITH %@", "sth").array
【讨论】:
【参考方案9】:Swift 4、Realm 3 的解决方案
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)
【讨论】:
【参考方案10】:使用 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()
【讨论】:
你是如何使用这个功能的? realm.objects(SomeModel.self).toArray()【参考方案11】:extension Results
func materialize() -> [Element]
return Array(self)
【讨论】:
【参考方案12】:使用 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
【讨论】:
以上是关于RealmSwift:将结果转换为 Swift 数组的主要内容,如果未能解决你的问题,请参考以下文章
Realm Swift 使用部分更新 collectionView
Swift 项目:ReactiveSwift+MVVM+RealmSwift+Alamofire+OM
RealmSwift 限制和获取最后 30 条记录到 tableview