Scala Idioms

Console multi-line input

   Iterator.continually(Console.readLine).takeWhile(_ != "").foreach(_.split(" ").map(_.toInt))

ListBuffer

 import scala.collection.mutable.ListBuffer;  
 var q = ListBuffer[List[Int]]();  
 5.until(10) foreach(i => q += (0 to i).toList)  

  • ArrayBuffer is the best-performing solution as long as you only need to append to one end
  • It's usually faster to append to an ArrayBuffer than to prepend to a List (or add an element to a ListBuffer)
    • Lists require the creation of a wrapper object
    • ArrayBuffer only needs to copy the object (generally twice): copies are usually faster than object creation

Seq (immutable)

 val q: Seq[List[Int]] = 5.until(10).map(i => (0 to i).toList).toSeq  
 => q: Seq[List[Int]] = Vector(List(0, 1, 2, 3, 4, 5), List(0, 1, 2, 3, 4, 5, 6), List(0, 1, 2, 3, 4, 5, 6, 7), List(0, 1, 2, 3, 4, 5, 6, 7, 8), List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))  

Either

 val dims = Seq(3,4,5)  
 def dim(line: String): Either[Boolean,Int] = {  
  try { Right(line.toInt) }  
  catch { case e => Left(false) }  
 }  
 dims.foreach { d =>   
  dims(d) match {  
   case Right(i: Int) => println(i)  
   case Left(b: Boolean) => println("fail")  
  }  
 }  

Tail recursion

 import scala.annotation.tailrec  
 class Factorial2 {  
  def factorial(n: Int): Int = {  
   @tailrec def factorialAcc(acc: Int, n: Int): Int = {  
    if (n <= 1) acc  
    else factorialAcc(n * acc, n - 1)  
   }  
   factorialAcc(1, n)  
  }  
 }  
 object factBot extends Factorial2 {  
  def compute(i: Int): Int = {  
   lazy val res:Int = factorial(i).toInt  
   return res  
  }  
 }  
 factBot.compute(10)  

Folding

 val words = Seq("hello", "dog")  
 ("" /: words) (_ +" "+ _)  
 import scalaz._  
 import Scalaz._  
 (∅[String] /: words) (_ +" "+ _)  

Collections

  • Scala: Seq ~ Java: List
  • Scala: List ~ Java: LinkedList
  • List has O(1) prepend and head/tail access.
  • Most other List operations are O(n)
  • A "Scala Array" is a Java Array
  • Array is the only parameterized data structure on JVM which does not suffer from boxing, which provides it superior performance in many ways.
  • IndexedSeq, on the other hand, is a trait in Scala extended by collections which provide effective constant time indexed access to their elements
    • position of elements (indices) deterministically defined.
    • There are generic, mutable and immutable versions of this trait, and an implicit conversion from Array to it.