Scan is a horizontal combination operator, but it's not the only one. Sometimes we want to group some consecutive values together, let's say in groups of two. We want to group H and E and make that an array and then emit that array, HE.
Then we want to group L with L. We're not grouping anymore these values with what happened before. So scan doesn't out of the box give us that, because the accumulator essentially aggregates all the values from the past.
Sometimes you don't want to do that. You would like to aggregate just the last two values or the last three values. That's why an operator called buffer exists. It allows you to group together values from the past and emit them as an array.
There are a couple of variants of it. There's buffer count. There's buffer time, buffer toggle, buffer when. Let's look at the easiest one which is buffer count.
Buffer count takes just one argument which is a number. That number specifies the size of the buffer or the maximum size of the array that will be emitted here as the output value.
Let's see how it works when it sees the H coming from the input. It will store that in an internal buffer here in the operator. Then it just continues. Once it sees E, it will also store E in the internal buffer.
Now it sees the internal buffer has H and E, so it's of size two. It hit the maximum that we provided here. That's when it emits the internal buffer here as an output. It's an array. We're just going to write actually HE, just as a smaller syntax here just in this case. HE here means an array.
Once it emitted that internal buffer, it will also clear what was inside here and it will continue. It sort of resets. Then it sees L and it stores L in internal buffer which has just one element now.
It sees L again and now the internal buffer has two elements. That's when it emits an array that has L and L, which is also an array. Then we just write it as LL.
Then it sees O, stores O in the internal buffer. Once it sees complete, it will emit the internal buffer even though it didn't have size two. It just had one element there, which was O. We also emit it as an array. Then we just complete.
Let's see how we can use this in practice. Call buffer count two. As we run this, we see HE, LL, O, and done. Now you can see that count two is basically specifying when do we close and reset these buffers, every time it hits the size two. Now it makes sense why we have all these variances.
You can specify how to close these buffers. Another variant is that of buffer time and you can specify how often do we close these buffers. If we close them every 900 milliseconds, if you plot 900 milliseconds in a inaudible diagram, it looks roughly like this.
That's what it's going to emit here. It closes the buffer. The buffer has only H. It closes the buffer here, and then it closes the buffer here. Then it emits O and complete. With buffer time, 900 millisecond, we will see H, E, L, L, O, and done.
There are also more variants. Sometimes you want to be more generic so you need to specify here a closing observable. Here you can really go custom.
You can specify another observable that will tell when to close these buffers. For instance, we can make another observable here which will be an interval of 900 milliseconds. Let's take three of those.
If we plot bar, we see 01. Sorry, this is this much and this much. Then it completes. That is bar. It's going to behave like this I guess. If we call it like that, basically we're giving bar as a guidance observable and how to close the buffers on this foo. We run that, we see H, E, L, L, and done.
I told you there's also buffer toggle and buffer when. These are a bit more advanced variants of buffer. We don't need to go through them because the idea is the same. You are able to provide an opening of the buffer and a closing as well.
The point of all of these buffer operators is that we're able to combine these values together as groups. We do that by specifying how to close these buffers and reset them. It's a horizontal combination operator.