Is there an more ideomatic way to split a stream by some predicate?

非 Y 不嫁゛ 提交于 2019-12-24 00:17:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!