我有3个序列可以找出是否需要保存更改文本文件:
- 文本ID (显示另一个文本时更改;其存在也表示"这是注释"( (
- 文本编辑状态更改(可以说,作为守卫条件,以确保用户真正编辑,而不仅仅是查看文本(
- 内容更改(当用户键入文本字段时(
产生元素的顺序是由此产生的组合。上面的列表代表快乐路径。
rxswift/rxtest测试用例:
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"))])
}
您将如何编写并保持高可读性?
我可以提出2个变体,我不喜欢这两个变体。
flatmap自然顺序的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
,主要是因为所产生的代码读取的读物就像我想告诉的故事一样:
withlatest从yoda style
自然顺序,这不会产生预期的结果:
// Does not work!
var textChange: Observable<TextChange> {
return identifier
.withLatestFrom(isEditing.filter { $0 == true }) { identifier, _ in identifier }
.withLatestFrom(identifier) { _, identifier in identifier }
.withLatestFrom(changedText) { identifier, text in (identifier, text) }
.map { identifier, text in TextChange(identifier: identifier, text: text) }
}
如果我坚持使用withLatestFrom
,因为它比flatMap
更有意图,则我必须在Yoda式的情况下写下序列组合,也就是说:向后。
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) }
}
因此,不是"自然"的情况:"当您有标识符并正在编辑时,然后进行文本更改,产生元素",我从结尾处讲故事,"当文本更改出现时,如果您正在编辑,如果您有标识符,则产生一个元素"。