
com.avsystem.commons.concurrent.ObservableExtensions.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-core_2.12 Show documentation
Show all versions of commons-core_2.12 Show documentation
AVSystem commons library for Scala
The newest version!
package com.avsystem.commons
package concurrent
import com.avsystem.commons.concurrent.ObservableExtensions.ObservableOps
import monix.eval.Task
import monix.reactive.Observable
import scala.util.Sorting
trait ObservableExtensions {
implicit final def observableOps[T](obs: Observable[T]): ObservableOps[T] = new ObservableOps(obs)
}
object ObservableExtensions extends ObservableExtensions {
final class ObservableOps[T](private val obs: Observable[T]) extends AnyVal {
import scala.collection.compat._
/** Creates a [[monix.eval.Task Task]] that upon execution
* will signal the first generated element of the source observable.
*
* Returns an `Opt.empty` for either empty source or null first element.
*/
def headOptL: Task[Opt[T]] = obs.headOptionL.map(_.toOpt)
/** Suppress the duplicate elements emitted by the source Observable.
*
* WARNING: this requires unbounded buffering.
*/
def distinct: Observable[T] = distinctBy[T](identity)
/** Given a function that returns a key for each element emitted by
* the source Observable, suppress duplicates items.
*
* WARNING: this requires unbounded buffering.
*/
def distinctBy[K](key: T => K): Observable[T] =
obs
.scan((MSet.empty[K], Opt.empty[T])) { case ((seenElems, _), elem) =>
(seenElems, elem.optIf(seenElems.add(key(elem))))
}
.collect { case (_, Opt(elem)) => elem }
/** Creates a [[monix.eval.Task Task]] that upon evaluation will collect all items from the source in a sorted order
* as an immutable sequence.
*
* WARNING: this requires unbounded buffering.
*/
def sortedL(implicit ord: Ordering[T], ct: ClassTag[T]): Task[ISeq[T]] =
obs
.toL(Array)
.map { arr =>
Sorting.stableSort(arr)
immutable.ArraySeq.unsafeWrapArray(arr)
}
/** Given a function that returns a key for each element emitted by the source Observable,
* returns a [[monix.eval.Task Task]] that upon evaluation will collect all items from the source sorted by that key
* in an immutable sequence.
*
* WARNING: this requires unbounded buffering.
*/
def sortedByL[R](f: T => R)(implicit ord: Ordering[R], ct: ClassTag[T]): Task[ISeq[T]] =
sortedL(ord on f, ct)
/** Given a collection factory `factory`, returns a [[monix.eval.Task Task]] that upon evaluation
* will collect all items from the source in the appropriate representation for the current element type `T`.
*
* Example uses for obs: Observable[(Int, String)]:
* {{{
* obs.toL(List) // Task[List[(Int, String)]]
* obs.toL(ArrayBuffer) //Task[ArrayBuffer[(Int, String)]]
* obs.toL(Map) //Task[Map[Int, String]]
* }}}
*
* WARNING: for infinite streams the process will eventually blow up
* with an out of memory error.
*/
def toL[R](factory: Factory[T, R]): Task[R] =
obs
.foldLeftL(factory.newBuilder)(_ += _)
.map(_.result())
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy