1

I have a ConnectableObservable which upon subscribe, will replay the last x items in their original order (oldest to newest) and any subsequent events after.

I am using this Observable as the backing store for an event blotter, however upon subscribe I would actually like the replayed items to be pushed/onNext'ed in the reverse order (newest to oldest) so I can display the most relevant items first.

Is this possible with standard RX operators or will I have to create a custom one?

Cheetah
  • 13,785
  • 31
  • 106
  • 190

1 Answers1

1

You can't do it with replay() as you'd need to get only the cached items on a non-terminated source. However, ReplaySubject lets you peek into it and get an array of items that you can reverse, then concatenate with the rest from the same subject but skipping the snapshot items just retrieved:

ReplaySubject<ItemType> subject = ReplaySubject.create();

source.subscribe(subject);

Observable<ItemType> result = Observable.defer(() -> {
    ItemType[] current = subject.getValues(new ItemType[0]);

    return Observable.range(0, current.length)
        .map(index -> current[current.length - 1 - index])
        .concatWith(subject.skip(current.length));
});
akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • 1
    I thought about solutions like this, but aren't these going to be subject to race conditions between the first part of the observable (playing back the buffer) and what it is concatWith (the later part)? – Cheetah Oct 20 '18 at 13:12