Skip to content
AgileLogics
6 min read

Collection Operations

Prerequisites: Functions as values, Sets and maps

Scala's collections share a rich set of operations. Chaining them replaces most loops.

Transforming and filtering

@main def transform(): Unit =
  val prices = List(12.0, 45.5, 3.25, 99.0, 18.0)

  println(prices.map(_ * 2))
  println(prices.filter(_ > 15))
  println(prices.filterNot(_ > 15))
  println(prices.partition(_ > 15))
  println(List("a,b", "c").flatMap(_.split(",")))
List(24.0, 91.0, 6.5, 198.0, 36.0)
List(45.5, 99.0, 18.0)
List(12.0, 3.25)
(List(45.5, 99.0, 18.0),List(12.0, 3.25))
List(a, b, c)
  • map transforms every element; filter keeps matching ones; partition splits into two lists.
  • flatMap maps each element to a collection and flattens the results.

Reducing to one value

@main def reduce(): Unit =
  val numbers = List(4, 8, 15, 16, 23, 42)

  println(numbers.sum)
  println(numbers.max)
  println(numbers.count(_ % 2 == 0))
  println(numbers.exists(_ > 40))
  println(numbers.forall(_ > 0))
  println(numbers.reduce(_ + _))
  println(numbers.foldLeft(0)((total, n) => total + n))
  println(numbers.foldLeft(List.empty[Int])((acc, n) => n :: acc))
108
42
4
true
true
108
108
List(42, 23, 16, 15, 8, 4)

foldLeft(start)(f) walks the collection, combining an accumulator with each element — the most general way to reduce a collection to one value of any type. The last line folds into a List, building the numbers in reverse.

Sorting, grouping, and slicing

@main def organize(): Unit =
  val people = List(("Ada", "London", 36), ("Linus", "Helsinki", 28),
    ("Grace", "New York", 45), ("Alan", "London", 41))

  println(people.sortBy(_._3).map(_._1))
  println(people.sortBy(p => -p._3).map(_._1))
  println(people.groupBy(_._2).view.mapValues(_.map(_._1)).toList.sortBy(_._1))
  println(people.take(2).map(_._1))
  println(people.drop(3).map(_._1))
  println(people.map(_._1).zip(1 to 4))
  println(List(1, 2, 3, 4, 5).sliding(2).toList)
List(Linus, Ada, Alan, Grace)
List(Grace, Alan, Ada, Linus)
List((Helsinki,List(Linus)), (London,List(Ada, Alan)), (New York,List(Grace)))
List(Ada, Linus)
List(Alan)
List((Ada,1), (Linus,2), (Grace,3), (Alan,4))
List(List(1, 2), List(2, 3), List(3, 4), List(4, 5))

A pipeline

@main def pipeline(): Unit =
  val text = "the quick brown fox jumps over the lazy dog the end"
  val top = text.split(" ")
    .groupBy(identity)
    .map((word, occurrences) => (word, occurrences.length))
    .toList
    .sortBy((word, count) => (-count, word))
    .take(3)
  println(top)
List((the,3), (brown,1), (dog,1))

Each step returns a new collection, so the pipeline reads top to bottom like a description of the result.

Practice

From List(3, 7, 2, 9, 4), compute the sum of the squares of the numbers greater than 3.

Show solution
@main def sumSquares(): Unit =
  val result = List(3, 7, 2, 9, 4).filter(_ > 3).map(n => n * n).sum
  println(result)
146