Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Rx(Swift)中以自然方式处理组合序列和条件_Swift_System.reactive_Rx Swift - Fatal编程技术网

如何在Rx(Swift)中以自然方式处理组合序列和条件

如何在Rx(Swift)中以自然方式处理组合序列和条件,swift,system.reactive,rx-swift,Swift,System.reactive,Rx Swift,我有3个序列来确定是否需要将更改保存到文本文件: 文本ID(在显示另一个文本时更改;它的出现也表示“此处有注释”) 文本编辑状态更改(可以说是一个保护条款,以确保用户真正在编辑而不仅仅是查看文本) 内容更改(当用户键入文本字段时) 元素产生的顺序对最终的组合至关重要。上面的列表代表了快乐之路 RxSwift/RxTest测试用例: func testContentThenEditingThenChange_ProducesEdit() { let identifier = schedu

我有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"))])
    }
    

    你如何写这篇文章并保持高可读性?

    我可以想出两种变体,这两种我都不喜欢

    按自然顺序对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) }
    }