I use RxJs to process data replayed from a file. Each data item contains a timereceived property. While replaying, I want to create buffers with all data items originally received within a given timespan x. In other words: I want to add all items to the current buffer while the timespan between the first buffer element received and the current element received is less than timespan x.
Example test:
it('should be able to create buffers based on time received', function() {
// given
let source = require('rx').Observable.from([
{val: 1, timereceived: 10},
{val: 2, timereceived: 20},
{val: 3, timereceived: 100},
{val: 4, timereceived: 110},
{val: 5, timereceived: 120}
]);
// when
let actual = app.bufferWithTimeReceived(source, 105).toArray();
// then
console.log(actual);
assert.equal(actual.length, 2); // first contains val 1-3, second val 4-5
})
If I would not replay all data from the file but just receive it in real time, I could use bufferWithTime for that and would be fine.
Update with another example
// given
let source = require('rxjs/Rx').Observable.from([
{val: 1, timereceived: 10},
{val: 2, timereceived: 20},
{val: 3, timereceived: 100},
{val: 4, timereceived: 110},
{val: 5, timereceived: 120},
{val: 6, timereceived: 9920},
{val: 7, timereceived: 9930}
]);
// when
app.bufferWithTimeReceived(source, 30).subscribe(console.log);
// then
// expected output would be [val 1-2][val 3-5][val 6-7] (empty arrays in between would be ok)
Update end
Now I played around with different approaches. My last one was:
exports.bufferWithTimeReceived = (source, timespan) => {
return Rx.Observable.defer(() => Rx.Observable.create(function (observer) {
let currBuffer = [];
source.subscribe(x => {
if (currBuffer.length == 0)
currBuffer = [x];
else {
if (x.timereceived-currBuffer[0].timereceived < timespan)
currBuffer.push(x);
else {
observer.onNext(currBuffer);
currBuffer = [x];
}
}
},
(err)=>observer.onError(err),
()=>observer.onCompleted());
}));
};
Unfortunately this only leads to oArrayObservable { source: Defer { _f: [Function] } } as an error message, which is not very helpful. I also wondered how Rx - Divide stream into segments (lists) by condition might could help me?!
Bonus question: Any hint how I could make this buffer overlapping?