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)
maptransforms every element;filterkeeps matching ones;partitionsplits into two lists.flatMapmaps 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