So, I was a curious about other solutions as well and decided to play around with it. I did come up with a different solution using windowing:
var src = new[] { 1, 2, 3, 4, 99, 5, 6, 7, 99, 8, 9, 10, 99 };
var obs = src.ToObservable().Publish().RefCount();
var windows =
obs
.Zip(
obs.Skip(2).Concat(Observable.Repeat(0, 2)),
(chase, lead) => (chase, lead))
.Publish(pub =>
pub
.Window(
pub.Where(x => x.lead == 99),
_ => pub.Skip(1)));
With this solution windows
is now an IObservable<IObservale<int>>
. The marble diagram looks something like this (I hope it makes sense, I'm waffling on the best way to represent an observable of observable):
src: 1--2--3--4--99--5--6--7--99--8--9--10--99--
WINDOW QUERY
: ------3--4--99-----------------------------
: -------------------6--7--99----------------
: --------------------------------9--10--99--
At first glance the behavior looks the same as your solution but after playing around with it I realized it behaves quite differently when you have overlapping widows.
If you use this src
instead:
// Note the adjacent 99s.
var src = new[] { 1, 2, 3, 4, 99, 99, 6, 7, 99, 8, 9, 10, 99 };
Your solution produces:
{{3, 4, 99}, {4,99,99}, {6, 7, 99}, {9, 10, 99}}
While the windowing solution yields this:
src: 1--2--3--4--99--99--6--7--99--8--9--10--99--
WINDOW QUERY
: ------3--4--99-----------------------------
: ---------4--99--99-------------------------
: -------------------6--7--99----------------
: --------------------------------9--10--99--
It doesn't seem that different until you call SelectMany
on both results. Then yours looks like this:
{ 3, 4, 99, 4, 99, 99, 6, 7, 99, 9, 10, 99 }
But the windowing solution interleaves the observables (which makes sense):
{ 3, 4, 4, 99, 99, 99, 6, 7, 99, 9, 10, 99 }
One thing to consider when using the Buffer
solution is that each buffer requires copying the buffer to a new list before it is returned. So, it's possible the windowing solution could perform better in some scenarios. I admit that I don't understand the inner workings of observables as well as I do enumerables so I would have to do some testing to be sure.
Anyway, it was fun to play around with and it could be a viable solution depending on what your end goal is.