关于 RxSwift/RxCocoa 与 combineLatest 绑定的问题

Question about RxSwift/RxCocoa binding with combineLatest

下面是一个将viewModel的字符串数组绑定到UITableView的简单例子。

我想再订阅一个 viewModel.randomString 并在单元格中使用它。
我尝试如下使用 combineLatest,但当然我无法绑定到 tableview。
您对如何实施它有什么想法吗?

class SimpleViewModel {
    var list = BehaviorRelay<[String]>(value: [])
    var randomString = BehaviorRelay<String>(value: "")
    
    func fetch() {
        // Request...
        list.accept(["result1", "result2", "result3"])
        randomString.accept("Random...")
    }
}

class SimpleViewController {
    let tableView = UITableView()
    let viewModel = ViewModel()
    
    func foo() {
        // It works well.
        viewModel.list.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
            cell.textLabel?.text = element
        }
        
        // I want to bind the viewModel.list to the tableView and use the viewModel.randomString string together.
        Observable.combineLatest(viewModel.list, viewModel.randomString)
        // How???
//            .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { (index, element, cell) in
//                cell.textLabel?.text = element + "RandomString" // I want to use the "RandomString" of viewModel.randomString
//            }
    }
}

您的 combineLatest 调用会生成一个 Observable<([String], String)>,但为了绑定到 table 视图项目,您需要一个 Sequence 事物的可观察对象。

([String], String) 不是序列。这是一对东西。您需要找到一种方法将其转换为一系列事物。由于您希望每个单元格都具有相同的 randomString,因此您可以使用这样的函数:

{ (list, randomString) in list.map { (element: [=10=], randomString: randomString) } }

将其转换为 [(String, String)],数组中每对中的第二个字符串为 randomString

如果只是把上面的函数传给Observable.map,就可以把一个Observable<([String], String)>转成Observable<[(String, String)]>:

Observable.combineLatest(viewModel.list, viewModel.randomString)
    .map { (list, randomString) in list.map { (element: [=11=], randomString: randomString) } }
    .bind(to: tableView.rx.items(cellIdentifier: "cell")) {
        (index, model, cell) in
        cell.textLabel?.text = model.element + model.randomString
    }.disposed(by: disposeBag)