====== L09. Scala collections ====== val letters = Vector("v", "m", "n", "i") /* the colon operator, allways indicates "associativity" * collection :@ element * * element #: collection * * */ letters :+ "z" "a" +: letters /* Ranges * (Int, Int) => Range * _.to(_) * * (Int, Int) => Range * _.until(_) * * (Range, Int) => Range * _.by(_) * * * */ 1.to(5) 1 to 5 1.until(5) 1 until 5 1 to 5 by 2 /* shorthand a b c for: a.b(c) */ /* In Scala you can define functions that are not named only with alphabetic characters */ trait Nat { def +(n: Nat): Nat def -(n: Nat): Nat // difference over naturals, not integers } case object Zero extends Nat { override def + (n: Nat): Nat = n override def - (n: Nat): Nat = Zero } case class Succ(n: Nat) extends Nat { override def + (m: Nat): Nat = Succ(n + m) override def - (m: Nat): Nat = m match { case Zero => Succ(n) case Succ(mp) => n - mp } } /* Maps */ val gradebook: Map[String,Int] = Map("John" -> 5 , "Anne" -> 9 , "Mike" -> 4) "John".->(5) // will return a pair ("John", 5) //indexing a map: gradebook("John") // will return 5 //what happens when a key is not present? //gradebook("Matei") /* how to deal with inexistent keys ? */ // Option 1: if (gradebook contains "Matei") gradebook("Matei") else "" // Option 2: val g2 = gradebook.withDefaultValue(0) // a new gradebook that returns 0 for non-existent keys // THIS MAKES GRADEBOOK A TOTAL FUNCTION g2 + ("Matei" -> 0) // updates the current map with a new key/value entry. If the key exists, it will be updated. The function returns a new map g2 ++ Map("A" -> 0, "B" -> 1) // merges two maps g2("Matei") // Option 3: // using the get function: gradebook.get("Matei") /* _.get(_) * * (Map[K,V],K) => Option[V] * */ /* trait Option[A] {} case class None[A]() extends Option[A] {} case class Some[A](value: A) extends Option[A] {} */ def head (l: List[Int]): Option[Int] = l match { case Nil => None case x :: _ => Some(x) } val list = List(1) head(list) match { case None => "Error, empty list" case Some(x) => "The first element is:"+x.toString }