如何在RxSwift中累积合并两个序列?

问题描述 投票:2回答:2

我有两个序列,我想将它们合并,以便将进入第二个序列的任何结果与第一个序列的最新结果进行累积合并。

A---------------B----------------------C------------- ...
-------1-2-----------3-------------------------------- ...

这样结果将是:

A-----A+1--A+1+2---B----B+3--------------C-------------

我该如何在Rx中执行此操作? (我正在使用RxSwift)

swift reactive-programming rx-swift
2个回答
1
投票

您可以使用combineLatest +bufferWhenhttps://stackblitz.com/edit/typescript-s1pemu

import {bufferWhen} from 'rxjs/operators';
import { timer, interval,combineLatest , } from 'rxjs';

// timerOne emits first value at 1s, then once every 4s
const timerOne$ = interval( 4000);
// timerTwo emits first value at 2s, then once every 4s
const timerTwo$ = interval(1000);
// timerThree emits first value at 3s, then once every 4s

// when one timer emits, emit the latest values from each timer as an array
combineLatest(
  timerOne$, 
  timerTwo$.pipe(bufferWhen(()=>timerOne$)), 
)
.subscribe(
  ([timerValOne, timerValTwo]) => {
    console.log(
    `Timer One Latest: ${timerValOne},
     Timer Two Latest: ${timerValTwo}`,
    );
    console.log('Total:', timerValOne+timerValTwo.reduce((acc,curr)=>acc+curr))
  }
);

0
投票

你去。希望您可以将其用作如何编写测试的模板,以建立所需的内容,然后编写生成该代码的代码。

enum Action<A, B> {
    case a(A)
    case b(B)
}

func example<A, B>(_ a: Observable<A>, _ b: Observable<B>) -> Observable<(A?, [B])> {
    return Observable.merge(a.map(Action.a), b.map(Action.b))
        .scan((A?.none, [B]())) { current, next in
            switch next {
                case .a(let a):
                    return (a, [])
                case .b(let b):
                    return (current.0, current.1 + [b])
            }
        }
}

这是一个证明它有效的测试:

class RxSandboxTests: XCTestCase {

    func testExample() {
        let scheduler = TestScheduler(initialClock: 0)
        let a = scheduler.createColdObservable([.next(0, "A"), .next(16, "B"), .next(39, "C")])
        let b = scheduler.createColdObservable([.next(7, 1), .next(9, 2), .next(21, 3)])

        let result = scheduler.start {
            example(a.asObservable(), b.asObservable())
                .map { Result(a: $0.0, b: $0.1) }
        }

        XCTAssertEqual(
            result.events,
            [
                .next(200, Result(a: "A", b: [])),
                .next(207, Result(a: "A", b: [1])),
                .next(209, Result(a: "A", b: [1, 2])),
                .next(216, Result(a: "B", b: [])),
                .next(221, Result(a: "B", b: [3])),
                .next(239, Result(a: "C", b: []))
            ]
        )
    }
}

struct Result: Equatable {
    let a: String?
    let b: [Int]
}
© www.soinside.com 2019 - 2024. All rights reserved.