+str #17383 implement intersperse

This commit is contained in:
Konrad Malawski 2015-10-16 01:55:20 +02:00
parent 99158f515c
commit 61c2213e02
10 changed files with 368 additions and 3 deletions

View file

@ -10,7 +10,7 @@ import akka.stream.impl.SplitDecision._
import akka.stream.impl.Stages.{ DirectProcessor, MaterializingStageFactory, StageModule }
import akka.stream.impl.StreamLayout.{ EmptyModule, Module }
import akka.stream.impl.fusing.{ DropWithin, GroupedWithin, TakeWithin }
import akka.stream.impl.{ Stages, StreamLayout }
import akka.stream.impl.{ ReactiveStreamsCompliance, Stages, StreamLayout }
import akka.stream.stage._
import org.reactivestreams.{ Processor, Publisher, Subscriber, Subscription }
@ -604,6 +604,71 @@ trait FlowOps[+Out, +Mat] {
*/
def fold[T](zero: T)(f: (T, Out) T): Repr[T, Mat] = andThen(Fold(zero, f.asInstanceOf[(Any, Any) Any]))
/**
* Intersperses stream with provided element, similar to how [[scala.collection.immutable.List.mkString]]
* injects a separator between a List's elements.
*
* Additionally can inject start and end marker elements to stream.
*
* Examples:
*
* {{{
* val nums = Source(List(1,2,3)).map(_.toString)
* nums.intersperse(",") // 1 , 2 , 3
* nums.intersperse("[", ",", "]") // [ 1 , 2 , 3 ]
* }}}
*
* In case you want to only prepend or only append an element (yet still use the `intercept` feature
* to inject a separator between elements, you may want to use the following pattern instead of the 3-argument
* version of intersperse (See [[Source.concat]] for semantics details):
*
* {{{
* Source.single(">> ") ++ Source(List("1", "2", "3")).intersperse(",")
* Source(List("1", "2", "3")).intersperse(",") ++ Source.single("END")
* }}}
*
* '''Emits when''' upstream emits (or before with the `start` element if provided)
*
* '''Backpressures when''' downstream backpressures
*
* '''Completes when''' upstream completes
*
* '''Cancels when''' downstream cancels
*/
def intersperse[T >: Out](start: T, inject: T, end: T): Repr[T, Mat] = {
ReactiveStreamsCompliance.requireNonNullElement(start)
ReactiveStreamsCompliance.requireNonNullElement(inject)
ReactiveStreamsCompliance.requireNonNullElement(end)
andThen(Intersperse(Some(start), inject, Some(end)))
}
/**
* Intersperses stream with provided element, similar to how [[scala.collection.immutable.List.mkString]]
* injects a separator between a List's elements.
*
* Additionally can inject start and end marker elements to stream.
*
* Examples:
*
* {{{
* val nums = Source(List(1,2,3)).map(_.toString)
* nums.intersperse(",") // 1 , 2 , 3
* nums.intersperse("[", ",", "]") // [ 1 , 2 , 3 ]
* }}}
*
* '''Emits when''' upstream emits (or before with the `start` element if provided)
*
* '''Backpressures when''' downstream backpressures
*
* '''Completes when''' upstream completes
*
* '''Cancels when''' downstream cancels
*/
def intersperse[T >: Out](inject: T): Repr[T, Mat] = {
ReactiveStreamsCompliance.requireNonNullElement(inject)
andThen(Intersperse(None, inject, None))
}
/**
* Chunk up this stream into groups of elements received within a time window,
* or limited by the given number of elements, whatever happens first.