Skip to content

Instantly share code, notes, and snippets.

@manjuraj
Last active April 16, 2019 14:07
Show Gist options
  • Save manjuraj/8c767ac4d6814be2813e to your computer and use it in GitHub Desktop.
Save manjuraj/8c767ac4d6814be2813e to your computer and use it in GitHub Desktop.
collect vs map, filter vs flatMap
// The collect method takes a PartialFunction as argument and maps the
// values defined for this partial function over it, skipping those
// outside the definition domain.
// Given a partial function pf, the following code:
//
// val pf: PartialFunction[A, B] =
// coll.collect(pf)
//
// is roughly equivalent to
//
// coll.filter(pf.isDefinedAt _).map(pf)
// filter and map returns List[Any]
scala> List("hello", 1, true, "world").filter(_.isInstanceOf[String]).map(identity)
res0: List[Any] = List(hello, world)
// flatMap returns List[String]
scala> List("hello", 1, true, "world") flatMap {
| case t: String => Some(t)
| case _ => None
| }
res1: List[String] = List(hello, world)
// collect returns List[String] and is concise
scala> List("hello", 1, true, "world") collect { case s: String => s }
res2: List[String] = List(hello, world)
// A instance of Seq, Set or Map is actually a partial function. So,
scala> val pets = List("cat", "dog", "frog")
pets: List[String] = List(cat, dog, frog)
scala> Seq(1, 2, 42) collect pets
res2: Seq[String] = List(dog, frog)
@GlulkAlex
Copy link

quote from Deprecating the Observer Pattern

The following collect combinator can be used to implement
other combinators:

def collect[B](p: PartialFunction[A, B]) =
Events.loop[B] { self =>
val x = self await outer
if (p isDefinedAt x) self << p(x)
self.pause
}

The resulting event stream emits those events from the original
stream applied to partial function p for which p is defined.
A PartialFunction can be written as a series of case clauses
as in a pattern match expression. We refer the enclosing
stream as outer. Notice that we use await and not awaitNext,
i.e., the combinator processes events immediately, starting
with the current one from outer if present.
Combinators map and filter can now both be implemented
in terms of collect:

def map[B](f: A => B): Events[B] =
collect { case x => f(x) }
def filter(p: A => Boolean): Events[A] =
collect { case x if p(x) => x }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment