问题
I have a stream of events, which I want to split into multiple streams, based on some property the event may have. Something like the following
let streams = new rx.Subject()
let stream = new rx.Subject()
input.subscribe((x) => {
stream.onNext(x)
if (!x.splitHere) return
streams.onNext(stream)
stream = new rx.Subject()
})
EDIT
Thank you for the hints about partition
and if
. While they do split one stream into multiple, they only provide two result streams.
Clarification What I need to do is to cut one stream into a variable number of streams, and the incision point be defined by the predicate.
# partition
in a---b---a---a---b--------b----a---
out1 a-------a---a-----------------a---
out2 ----b-----------b--------b--------
# what I need is to cut after every X
in a-b-c-X-d-e-f-g-h-X-i-X-j-k-l-m-n-
out v a-b-c-X
v -d-e-f-g-h-X
v -i-X
v -j-k-l-m-n-
回答1:
window
does this.
const streams = input
.filter(x => x !== 'X')
.window(input.filter(x => x === 'X'));
Using partition
and array destructuring you can get something that (in my opinion) reads very nicely:
const [ incisions, items ] = input.partition(x => x === 'X');
const streams = items.window(incisions);
回答2:
Yes, there's an operator called partition
:
const source$ = Rx.Observable.from([{ a: 'value' }, { b: 'value' }]);
const [hasA$, doesNotHaveA$] = source$.partition(x => Boolean(x.a));
Typically if you want to derive streams that satisfy some criteria/predicate, the best way to do so is to use the filter
operator:
const hasA$ = source$.filter(x => Boolean(x.a));
const satisfiesOtherCriteria$ = source$.filter(somePredicate));
回答3:
Suposing you are referring to splitting (i.e. you get several streams out of one), you have a very nice and thorough treatment of that question here : RxJS modeling if else control structures with Observables operators
Here is the summary :
There are a couple operators that you could use to emulate this:
In order from most likely what you are asking for :
- partition
- groupBy
- if
- case
Code examples are provided in the link.
If you are referring to filtering (getting one stream out of one stream but skipping some values), then the filter
operator is your best bet. There are also other operators which do some kind of filtering, such as distinct
, or distinctUntilChanged
, skip
etc.
来源:https://stackoverflow.com/questions/36065735/is-there-an-more-ideomatic-way-to-split-a-stream-by-some-predicate