Hi again (;
I do some fun for myself with RxSwift and I encountered the problem: How to create one Observable with array of Strings from 3 TextFields. I resolved it like in the code below, but it looks messy. Is any way to do it cleaner?
lazy var textFieldsOutput: Observable<[String]> = { [unowned self] in
return Observable<[String]>.create({ (observer) -> Disposable in
var texts: [String] = self.textFields.map { $0.text ?? "" }
for (i, textField) in self.textFields.enumerated() {
self.textFields[i].rx.text
.skip(1)
.subscribe(onNext: { text in
texts[i] = text ?? ""
observer.onNext(texts)
}).addDisposableTo(self.bag)
}
return Disposables.create()
})
}()
Hi, what you need is combineLatest
, check Chapter 9 the “Combining Elements” part
1 Like
thanks (: I figured out this result.
let one = self.textFields[0].rx.text.asObservable()
let two = self.textFields[1].rx.text.asObservable()
let three = self.textFields[2].rx.text.asObservable()
return Observable.combineLatest(one, two, three) {
return [$0, $1, $2].flatMap { $0 }
}
much better! but maybe is some way to make it less hard typed?
self.textFields.map { $0.rx.text.asObservable() }
this code returns [Observable< String? >]. Is any easy way to convert it to Observable<[String?]> ?
yes, combineLatest
also takes an array of observables (instead of a list of observables)
1 Like
Thank you Marin!
No my code looks like this if anyone wonders
lazy var textFieldsOutput: Observable<[String]> = { [unowned self] in
let observables = self.textFields.map { $0.rx.text.asObservable() }
return Observable.combineLatest(observables).map{$0.flatMap{$0}}
}()
Much shorter than in first post
1 Like