如何在Rx(Swift)中以自然方式处理组合序列和条件
我有3个序列来确定是否需要将更改保存到文本文件:如何在Rx(Swift)中以自然方式处理组合序列和条件,swift,system.reactive,rx-swift,Swift,System.reactive,Rx Swift,我有3个序列来确定是否需要将更改保存到文本文件: 文本ID(在显示另一个文本时更改;它的出现也表示“此处有注释”) 文本编辑状态更改(可以说是一个保护条款,以确保用户真正在编辑而不仅仅是查看文本) 内容更改(当用户键入文本字段时) 元素产生的顺序对最终的组合至关重要。上面的列表代表了快乐之路 RxSwift/RxTest测试用例: func testContentThenEditingThenChange_ProducesEdit() { let identifier = schedu
func testContentThenEditingThenChange_ProducesEdit() {
let identifier = scheduler.createHotObservable([next(300, "identifier")])
let isEditing = scheduler.createHotObservable([next(400, true)])
let changedText = scheduler.createHotObservable([next(500, "foo")])
let viewModel = TextEditingViewModel(
identifier: identifer.asObservable(),
changedText: changedText.asObservable(),
isEditing: isEditing.asObservable())
let result = scheduler.start { viewModel.textChange }
XCTAssertEqual(result.events, [next(500, TextChange(identifier: "identifier", text: "foo"))])
}
你如何写这篇文章并保持高可读性?我可以想出两种变体,这两种我都不喜欢 按自然顺序对3个序列进行平面映射 这是一个可行的实现
struct TextEditingViewModel {
let identifier: Observable<Identifier>
let changedText: Observable<String>
let isEditing: Observable<Bool>
var textChange: Observable<TextChange> {
return identifier
.flatMap { identifier in self.isEditing.filter { $0 == true }.map { _ in identifier } }
.flatMap { identifier in self.changedText.map { text in (identifier, text) } }
.map { identifier, text in TextChange(identifier: identifier, text: text) }
}
}
如果我坚持使用withLatestFrom
,因为它比flatMap
显示了更多的意图,那么我必须以尤达风格编写序列组合,即:向后
var textChange: Observable<TextChange> {
return changedText
.withLatestFrom(isEditing.filter { $0 == true }) { text, _ in text }
.withLatestFrom(identifier) { text, identifier in (identifier, text) }
.map { identifier, text in Edit(identifier: identifier, text: text) }
}
var textChange:可观察{
返回已更改的文本
.withLatestFrom(isEditing.filter{$0==true}){text,uUin text}
.withLatestFrom(标识符){text,标识符位于(标识符,文本)}
.map{标识符,编辑中的文本(标识符:标识符,文本:文本)}
}
因此,与“当你有一个标识符并且正在编辑,然后一个文本更改进入,产生一个元素”的“自然”情况不同,我从结尾讲故事“当一个文本更改进入,只有当你正在编辑,如果你有一个标识符,然后产生一个元素”
var textChange: Observable<TextChange> {
return changedText
.withLatestFrom(isEditing.filter { $0 == true }) { text, _ in text }
.withLatestFrom(identifier) { text, identifier in (identifier, text) }
.map { identifier, text in Edit(identifier: identifier, text: text) }
}