Collections
Scala hat eine reiche, standardmäßig unveränderliche Collection-Bibliothek: List, Vector, Set, Map, Seq, Array. Operationen liefern neue Collections.
@main def main(): Unit =
val z = List(5, 3, 9, 1, 7)
println(s"${z.head} ${z.tail} ${z.last} ${z.length} ${z(2)} ${z.take(2)} ${z.drop(3)}")
println(s"${0 :: z} ${z :+ 100} ${z ++ List(8)} ${z.reverse} ${z.sorted} ${z.sortBy(-_)} ${z.sortWith(_ > _)}")
println(s"${z.map(_ * 2)} ${z.filter(_ > 4)} ${z.sum} ${z.product} ${z.min} ${z.max} ${z.size}")
println(s"${z.exists(_ > 8)} ${z.forall(_ > 0)} ${z.count(_ % 2 == 1)} ${z.find(_ > 5)} ${z.indexOf(9)} ${z.contains(3)}")
println(s"${z.foldLeft(0)(_ + _)} ${z.reduce(_ max _)} ${z.partition(_ > 4)} ${z.zip("abcde")} ${z.sliding(2).toList}")
println(s"${z.grouped(2).toList} ${z.takeWhile(_ > 2)} ${z.dropWhile(_ > 2)} ${z.span(_ > 2)} ${z.splitAt(2)}")
println(s"${List(List(1, 2), List(3)).flatten} ${List("ab", "cd").flatMap(_.toList)} ${z.distinct} ${z.mkString(", ")} ${z.mkString("[", ";", "]")}")
println(s"${List(1, 2, 2, 3, 3, 3).groupBy(identity).view.mapValues(_.size).toMap.toList.sorted}")
println(s"${List("a", "bb", "ccc").map(_.length)} ${(1 to 5).toList.scanLeft(0)(_ + _)} ${List.fill(3)("x")} ${List.range(0, 10, 3)} ${List.tabulate(4)(i => i * i)}")
println(s"${z.zipWithIndex} ${z.lift(10)} ${z.lift(1)} ${z.collect { case x if x > 4 => x * 10 }} ${z.maxBy(x => (x - 5).abs)}")Ausgabe
5 List(3, 9, 1, 7) 7 5 9 List(5, 3) List(1, 7) List(0, 5, 3, 9, 1, 7) List(5, 3, 9, 1, 7, 100) List(5, 3, 9, 1, 7, 8) List(7, 1, 9, 3, 5) List(1, 3, 5, 7, 9) List(9, 7, 5, 3, 1) List(9, 7, 5, 3, 1) List(10, 6, 18, 2, 14) List(5, 9, 7) 25 945 1 9 5 true true 5 Some(9) 2 true 25 9 (List(5, 9, 7),List(3, 1)) List((5,a), (3,b), (9,c), (1,d), (7,e)) List(List(5, 3), List(3, 9), List(9, 1), List(1, 7)) List(List(5, 3), List(9, 1), List(7)) List(5, 3, 9) List(1, 7) (List(5, 3, 9),List(1, 7)) (List(5, 3),List(9, 1, 7)) List(1, 2, 3) List(a, b, c, d) List(5, 3, 9, 1, 7) 5, 3, 9, 1, 7 [5;3;9;1;7] List((1,1), (2,2), (3,3)) List(1, 2, 3) List(0, 1, 3, 6, 10, 15) List(x, x, x) List(0, 3, 6, 9) List(0, 1, 4, 9) List((5,0), (3,1), (9,2), (1,3), (7,4)) None Some(3) List(50, 90, 70) 9
Maps und Sets
@main def main(): Unit =
val alter = Map("Mia" -> 17, "Tom" -> 25)
val mehr = alter + ("Zoe" -> 31)
val ohne = mehr - "Tom"
println(s"${alter("Mia")} ${alter.get("Ben")} ${alter.getOrElse("Ben", 0)} ${mehr.size} ${ohne.keys.toList.sorted}")
println(mehr.toList.sortBy(_._1))
println(mehr.map((k, v) => (k.toUpperCase, v + 1)).toList.sorted)
println(mehr.filter((_, v) => v > 20).keys.toList.sorted)
println(mehr.values.sum)
for (name, a) <- mehr.toList.sortBy(_._1) do println(s"$name => $a")
val zaehler = "mississippi".groupBy(identity).map((c, s) => c -> s.length)
println(zaehler.toList.sorted)
val wort = "ein kleiner langer Satz mit drei".split(" ").toList
println(wort.groupBy(_.length).toList.sortBy(_._1))
val s = Set(3, 1, 2, 3, 1)
println(s"${s.size} ${s.contains(2)} ${(s + 9).toList.sorted} ${(s & Set(1, 9)).toList} ${(s | Set(7)).toList.sorted} ${(s -- Set(1)).toList.sorted}")
import scala.collection.mutable
val veraenderlich = mutable.Map("a" -> 1)
veraenderlich("b") = 2
veraenderlich += ("c" -> 3)
val puffer = mutable.ArrayBuffer(1, 2)
puffer += 3
puffer.prepend(0)
println(s"${veraenderlich.toList.sorted} ${puffer}")Ausgabe
17 None 0 3 List(Mia, Zoe) List((Mia,17), (Tom,25), (Zoe,31)) List((MIA,18), (TOM,26), (ZOE,32)) List(Tom, Zoe) 73 Mia => 17 Tom => 25 Zoe => 31 List((i,4), (m,1), (p,2), (s,4)) List((3,List(ein, mit)), (4,List(Satz, drei)), (6,List(langer)), (7,List(kleiner))) 3 true List(1, 2, 3, 9) List(1) List(1, 2, 3, 7) List(2, 3) List((a,1), (b,2), (c,3)) ArrayBuffer(0, 1, 2, 3)
Pattern Matching
match zerlegt Werte nach Struktur. Das ist eines der Kernmerkmale von Scala:
case class Punkt(x: Int, y: Int)
def beschreibe(wert: Any): String = wert match
case 0 => "null"
case n: Int if n < 0 => s"negative Zahl $n"
case n: Int => s"Zahl $n"
case s: String if s.isEmpty => "leerer Text"
case s: String => s"Text mit ${s.length} Zeichen"
case Punkt(0, 0) => "Ursprung"
case Punkt(x, 0) => s"auf der x-Achse bei $x"
case Punkt(x, y) => s"Punkt $x/$y"
case List() => "leere Liste"
case List(a) => s"Liste mit einem Element $a"
case List(a, b, _*) => s"Liste beginnt mit $a, $b"
case (a, b) => s"Tupel $a, $b"
case Some(x) => s"Some($x)"
case None => "None"
case _ => "unbekannt"
def summe(l: List[Int]): Int = l match
case Nil => 0
case kopf :: rest => kopf + summe(rest)
@main def main(): Unit =
val tests: List[Any] = List(0, -5, 42, "", "Scala", Punkt(0, 0), Punkt(3, 0), Punkt(1, 2), List(), List(7), List(1, 2, 3), (1, "x"), Some(5), None, 3.5)
tests.foreach(t => println(beschreibe(t)))
println(summe(List(1, 2, 3, 4)))
val (a, b) = (1, 2)
val Punkt(px, py) = Punkt(5, 6)
val erstes :: zweites :: _ = List(10, 20, 30): @unchecked
println(s"$a $b $px $py $erstes $zweites")
val ergebnis = List(1, 2, 3, 4, 5, 6).collect:
case n if n % 2 == 0 => n * n
println(ergebnis)Ausgabe
null negative Zahl -5 Zahl 42 leerer Text Text mit 5 Zeichen Ursprung auf der x-Achse bei 3 Punkt 1/2 leere Liste Liste mit einem Element 7 Liste beginnt mit 1, 2 Tupel 1, x Some(5) None unbekannt 10 1 2 5 6 10 20 List(4, 16, 36)
Merke
- Collections sind unveränderlich:
List,Vector,Set,Map; veränderlich inscala.collection.mutable - Mächtige Operationen:
map,filter,foldLeft,groupBy,zip,sliding,flatMap matchmit Mustern: Werte, Typen,case class, Listen, Tupel, Guards (if)- Pattern Matching zerlegt auch in
val-Definitionen
Aufgabe
Zähle mit groupBy die Wörter eines Satzes und gib die häufigsten aus.