Skip to content

Recap: Collections

Rohit edited this page Jan 2, 2017 · 3 revisions

Collections share a common set of general methods:

Core Methods:

  • map
  • flatMap
  • filter
  • foldLeft
  • foldRight

map vs flatMap

map works by applying a function to each element in the list. flatMap works applying a function that returns a sequence for each element in the list, and flattening the results into the original list.

val list = List(1,2,3,4)
val one = list.map(x => x*2)                   // List(2, 4, 6, 8)
val two = list.flatMap(x => Vector(x*2, x*3))  // List(2, 3, 4, 6, 6, 9, 8, 12)

filter vs withFilter

filter will take the original collection and produce a new collection, but withFilter will non-strictly (ie. lazily) pass unfiltered values through to later map/flatMap/withFilter calls, saving a second pass through the (filtered) collection. Hence it will be more efficient when passing through to these subsequent method calls.

For expressions

Simplify combinations of map, flatMap and filter:

// Instead of:
(1 until n) flatMap (i =>
    (1 until i) filter (j => isPrime(i + j)) map
        (j => (i, j)))

// one can write:
for {
    i <- 1 until n
    j <- 1 until i
    if isPrime(i + j)
} yield (i, j)

For-expressions and Pattern Matching

The left-hand side of a generator may also be a pattern.

Example
val data: List[JSON] = ...
for {
    JObj(bindings) <- data
    JSeq(phones) = bindings("phoneNumbers")
    JObj(phone) <- phones
    JStr(digits) = phone("number")
    if digits startsWith ”212”
} yield (bindings("firstName"), bindings("lastName"))
Clone this wiki locally