Consider using the zip operator to zip together two infinite Observables, one of which emits items twice as frequently as the other.
The current implementation is loss-l
I'm adding another answer for clarity, as it comes after the accepted answer (but builds on my previous answer).
Forgive me if I've misunderstood, but I was expecting the solution to handle switching emission rates:
then I switch between their emitting rates,
The test supplied doesn't switch emission rate until after the first stream stops,
Stream1: 1 2 3 4 5 6 7
Stream2: 10 20 30 40 50 60 70
so I've tried another test
Stream1: 1 2 3 4 5 6
Stream2: 10 20 30 40 50 60
The test data for this stream is
s1.next(1); s1.next(2); s2.next(10); s2.next(20); s1.next(3); s1.next(4);
s2.next(30); s2.next(40); s1.next(5); s1.next(6); s2.next(50); s2.next(60);
From my understanding, the accepted answer fails this test.
It outputs
[1, 10]
[3, 20]
[4, 30]
[5, 40]
[6, 50]
whereas I'd expect to see
[1, 10]
[3, 30]
[5, 50]
if the operator is to be symmetrical (commutative?)
Enhancing my previous answer
This solution is built from basic operators, so is arguably easier to understand. I can't speak to it's efficiency, perhaps will test that in another iteration.
const s1 = new Rx.Subject();
const s2 = new Rx.Subject();
const tagged1 = s1.map(x=>[x,1])
const tagged2 = s2.map(x=>[x,2])
const merged = tagged1.merge(tagged2)
const fresh = merged.scan((acc, x) => {
return x[1] === acc[1] ? acc : x
})
.distinctUntilChanged() //fresh ones only
const dekeyed = fresh.map(keyed => keyed[0])
const paired = dekeyed.pairwise()
let index = 0
const sequenced = paired.map(x=>[x,index++])
const alternates = sequenced.filter(x => x[1] % 2 === 0)
const deindexed = alternates.map(x=>x[0])
or in more compact form if preferred
let index = 0
const output =
s1.map(x=>[x,1]).merge(s2.map(x=>[x,2])) // key by stream id
.scan((acc, x) => {
return x[1] === acc[1] ? acc : x
})
.distinctUntilChanged() //fresh ones only
.map(keyed => keyed[0]) // de-key
.pairwise() // pair
.map(x=>[x,index++]) // add a sequence no
.filter(x => x[1] % 2 === 0) // take even sequence
.map(x=>x[0]) // deindex
For testing, CodePen (refresh CodePen page after opening console, for better display)