有没有办法简化数据转换?
Is there a way to simplify data trasforming?
有一个函数从服务器调用 API 到 return Observable<DataFromServer>
。
我想把它转化成UI中必要的数据,做成Observable<[DataForUI>
。
我做了一个示例如下,但我想简化转换部分。
有办法可以告诉我吗?
// Models
struct DataFromServer {
var name: String
var score: Int
}
struct DataForUI {
var displayName: String
var displayScore: String
}
// API function
func fetch() -> Observable<[DataFromServer]> {
// ...
}
// output
var resultData: PublishRelay<[DataForUI]> = PublishRelay()
// Sample Code
ActionSubject // Trigger for fetch()
.flatMapLatest { fetch() }
// I want to simplify the code below.
.flatMap { data -> Observable<[DataForUI]> in
return Observable.just(data.map {
DataForUI(displayName: “convert \([=10=].name)”, displayScore: “convert \([=10=].score)”)
})
}
.bind(to: resultData)
.disposed(by: disposeBag)
你有很多不同的选择...
首先,我会做一个扩展来处理实际的转换:
extension DataForUI {
init(serverData: DataFromServer) {
displayName = "convert \(serverData.name)"
displayScore = "convert \(serverData.score)"
}
}
那么你可以 map/map:
func sampleCode(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.map { [=11=].map { DataForUI(serverData: [=11=]) } }
.bind(to: resultData)
.disposed(by: disposeBag)
}
这是相同的想法,但传入的是 init 方法而不是闭包:
func sample1Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.map { [=12=].map(DataForUI.init(serverData:)) }
.bind(to: resultData)
.disposed(by: disposeBag)
}
您可以在 Observable 上编写一个扩展来处理 map/map 操作:
extension ObservableType where Element: Sequence {
func mapArray<Result>(_ transform: @escaping (Self.Element.Element) throws -> Result) -> RxSwift.Observable<[Result]> {
map { try [=13=].map(transform) }
}
}
然后像这样使用扩展名:
func sample2Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.mapArray { DataForUI(serverData: [=14=]) }
.bind(to: resultData)
.disposed(by: disposeBag)
}
或免积分版:
func sample3Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest(fetch)
.mapArray(DataForUI.init(serverData:))
.bind(to: resultData)
.disposed(by: disposeBag)
}
有一个函数从服务器调用 API 到 return Observable<DataFromServer>
。
我想把它转化成UI中必要的数据,做成Observable<[DataForUI>
。
我做了一个示例如下,但我想简化转换部分。
有办法可以告诉我吗?
// Models
struct DataFromServer {
var name: String
var score: Int
}
struct DataForUI {
var displayName: String
var displayScore: String
}
// API function
func fetch() -> Observable<[DataFromServer]> {
// ...
}
// output
var resultData: PublishRelay<[DataForUI]> = PublishRelay()
// Sample Code
ActionSubject // Trigger for fetch()
.flatMapLatest { fetch() }
// I want to simplify the code below.
.flatMap { data -> Observable<[DataForUI]> in
return Observable.just(data.map {
DataForUI(displayName: “convert \([=10=].name)”, displayScore: “convert \([=10=].score)”)
})
}
.bind(to: resultData)
.disposed(by: disposeBag)
你有很多不同的选择...
首先,我会做一个扩展来处理实际的转换:
extension DataForUI {
init(serverData: DataFromServer) {
displayName = "convert \(serverData.name)"
displayScore = "convert \(serverData.score)"
}
}
那么你可以 map/map:
func sampleCode(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.map { [=11=].map { DataForUI(serverData: [=11=]) } }
.bind(to: resultData)
.disposed(by: disposeBag)
}
这是相同的想法,但传入的是 init 方法而不是闭包:
func sample1Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.map { [=12=].map(DataForUI.init(serverData:)) }
.bind(to: resultData)
.disposed(by: disposeBag)
}
您可以在 Observable 上编写一个扩展来处理 map/map 操作:
extension ObservableType where Element: Sequence {
func mapArray<Result>(_ transform: @escaping (Self.Element.Element) throws -> Result) -> RxSwift.Observable<[Result]> {
map { try [=13=].map(transform) }
}
}
然后像这样使用扩展名:
func sample2Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest { fetch() }
.mapArray { DataForUI(serverData: [=14=]) }
.bind(to: resultData)
.disposed(by: disposeBag)
}
或免积分版:
func sample3Code(actionSubject: Observable<Void>, disposeBag: DisposeBag) {
actionSubject
.flatMapLatest(fetch)
.mapArray(DataForUI.init(serverData:))
.bind(to: resultData)
.disposed(by: disposeBag)
}