Michael Sjoeberg

A Scala Primer and Cheat Sheet.

# Notes

Execute code.

object Main {
    // do something

    def main(args: Array[String]) {
        // do something
    }
}

Compile with: $ scalac filename.scala.

Run with: $ scala filename.

Handle exceptions.

try {
    // do something
}
catch {
    case a: ArithmeticException => println("This is an arithmetic error: " + a)

    case b: Throwable => println("Error: " + b)
}
finally {
    // do something
}

Add build system to compile and run with https://www.sublimetext.com/.

{
    "cmd": ["scala", "$file"],
    "path": "$PATH:/usr/local/bin",
    "file_regex": "^(.+):(\\d+): .+: (.+)",
    "selector": "source.scala"
}

# Arithmetic Operators

10 + 20                     // 30
20 - 10                     // 10
10 * 20                     // 200
20 / 10                     // 2

Automatic floating point conversion.

10.0 + (10 + 20)            // 40.0
20.0 - (10 + 10)            // 0.0
10.0 * (10 * 2)             // 200.0

Common division error.

30 / 20                     // 1
30.0 / 20.0                 // 1.5

Modulo, or remainder.

12.5 % 10.0                 // 2.5
10.0 % 20.0                 // 10.0

Built in numerical operations.

List(1, 2, 3, 4).sum        // 10
List(1, 2, 3, 4).min        // 1
List(1, 2, 3, 4).max        // 4

See Math for more.

# Variables

val is immutable.

val x: Int = 6
val y: String = "String"
val z: Double = 1.05
x, y, z                         // (6,String,1.05)
x.getClass.getSimpleName        // int
y.getClass.getSimpleName        // String
z.getClass.getSimpleName        // double

var is mutable.

var a = x                       // 6
a = a + 2                       // 8

Multiple assignments.

val (x, y, z) = (6, "String", 1.05)     // (6,String,1.05)

List assignments.

val List(d, t, v) = List(230, 45, 12)   // (230,45,12)

String assignments.

val string: String = "100B"
val Array(a, b, c, d) = string.toArray  // (1,0,0,B)

# String Indexing

val string: String = "proton"
string.charAt(0)                        // p
string.slice(0,4)                       // prot

Indexing using length.

string.length                                           // 6
string.substring(0, string.length)                      // proton
string.substring(string.length - 4, string.length)      // oton

# String Operations

"kilo" ++ "meter"                       // kilometer
"A" * 4                                 // AAAA
val string: String = "proton neutron"
string.capitalize                       // Proton neutron
string.toUpperCase                      // PROTON NEUTRON
string.toLowerCase                      // proton neutron

Counting and finding letters in text.

string.count(_ == 'p')                  // 1
string.indexOf("t")                     // 3

Removing whitespace from a string.

val string: String = "    some text    "
string.trim                             // some text

# Data Structures

# Lists

Lists are immutable.

val list_one: List[String] = List("Alpha", "Beta")          // List(Alpha, Beta)
val list_two: List[Any] = List(200, -2, List(1.0, 0.0))     // List(200, -2, List(1.0, 0.0))
val list_range: List[Int] = List.range(1, 10)               // List(1, 2, 3, 4, 5, 6, 7, 8, 9)

Concatenate lists.

val list_all = list_one ++ list_two             // List(Alpha, Beta, 200, -2, List(1.0, 0.0))

Create list with item added to an existing list.

val list_one_new = "Gamma"  :: list_one         // List(Gamma, Alpha, Beta)

List operations.

list_one_new.length                             // 3
list_one_new.sorted                             // List(Alpha, Beta, Gamma)
list_two.head                                   // 200
list_two.last                                   // List(1.0, 0.0)
list_range.filter(_ > 5)                        // List(6, 7, 8, 9)

Create list from a string.

val list_char: List[Char] = ("100B").toList     // List(1, 0, 0, B)

# Tuples

Tuples are immutable.

val tuple_one = (1.0, "String", 4)              // (1.0,String,4)
val tuple_two = ("Alpha", "Bravo", (1, 0))      // (Alpha,Bravo,(1,0))
tuple_one._2                                    // String
tuple_two._3._2                                 // 0

Assign each value in tuple to a variable, see Variables for more.

val (first, second, third) = ("Alpha", "Beta", "Gamma")
first                                   // Alpha
second                                  // Beta
third                                   // Gamma

# Maps

Maps, or hash tables, with key:value pairs are immutable.

val map_any = Map("Adam" -> List("adam@email.com", 2445055),
                  "Bard" -> "bard@email.com" )
map_any("Adam")                                     // List(adam@email.com, 2445055)
map_any.contains("Bard")                            // true
map_any.exists(_ == "Bard" -> "bard@email.com")     // true

Mutable map.

val map_mutable = scala.collection.mutable.Map[String, Int]()
map_mutable += ("Alpha" -> 1, "Beta" -> 2)          // Map(Beta -> 2, Alpha -> 1)
map_mutable -= "Beta"                               // Map(Alpha -> 1)
map_mutable("Alpha") = 100                          // Map(Alpha -> 100)

# Sets

Sets are immutable.

val set_numbers: Set[Int] = Set(1, 3, 5, 7, 9)      // Set(5, 1, 9, 7, 3)
set_numbers.contains(3)                             // true
set_numbers.contains(2)                             // false

Mutable set.

val set_mutable_one = scala.collection.mutable.Set(1, 3, 5)
val set_mutable_two = scala.collection.mutable.Set(5, 7, 9)
set_mutable_two += 11                               // Set(9, 5, 7, 11)
set_mutable_two -= 11                               // Set(9, 5, 7)

Set operations.

val A = set_mutable_one.clone
val B = set_mutable_two.clone
A | B                                               // Set(9, 1, 5, 3, 7)
A & B                                               // Set(5)
A &~ B                                              // Set(1, 3)
A union B                                           // Set(9, 1, 5, 3, 7)
A intersect B                                       // Set(5)
A diff B                                            // Set(1, 3)
A subsetOf B                                        // false

# Conditionals

# If-Else Statements

val a: Double = 1.0
val b: Double = 5.0
if (a < 1.0) {
    // do something
}
else if (a == 1.0) {
    // do something
}
else {
    // do something
}

# Logical Operators

val T: Boolean = true
val F: Boolean = false
T || F                      // true
T && (T && F)               // false
!T                          // false
!(!T)                       // true
1 == 2                      // false
1 != 2                      // true

# Loops

# For

val numbers: List[Int] = List(1, 2, 3, 4)       // List(1, 2, 3, 4)
for (number <- numbers) {
    // do something
}

Nested for loops.

for (i <- List.range(1, 5)) {
    for (j <- List.range(1, 5)) {
        // do something
    }
}

Using for loops and maps.

val map: Map[String, Int] = Map("Alpha" -> 1, "Beta" -> 2)
for ((k, v) <- map) {
    println(k, v)                       // (Alpha,1) (Beta,2)
}

# While

var a = 0
var b = 5
while (a < b) {
    // do something

    a += 1
}

# Functions

def function(): Boolean = {
    // do something

    return true
}
def add(a:Int, b:Int): Int = {
    
    return a + b
}
add(2, 3)                               // 5

Default arguments.

def add(a:Int, b:Int = 3): Int = {
    
    return a + b
}
add(2)                                  // 5

Multiple return values.

def add(a:Int, b:Int): (Int, Int, Int) = {
    var result = a + b
    
    return (a, b, result)
}
val (a, b, result) = add(2, 3)          // (2,3,5)

Documentation (scaladoc).

/** Print the argument passed to function.
 *
 *  @param arg an argument
 */
def print(arg:String) = {
    
    // print argument
    println(arg)
}

# Classes

class Money(val a:Int, val c:String) {
    var amount: Int = a
    var currency: String = c
    
    override def toString = amount.toString ++ " " ++ currency
}

Create a new instance of class.

val money = new Money(220, "EUR")

money.amount, money.currency                // (220,EUR)
println(money)                              // 220 EUR

Subclasses.

class VirtualMoney(override val a:Int, override val c:String, val d:String) extends Money(a, c) {

    var date: String = d
    
    override def toString = amount.toString ++ " " ++ currency ++ " (use before " ++ date ++ ")"
}
val virtual_money = new VirtualMoney(20, "DIS", "2018-12-31")
println(virtual_money)                      // 20 DIS (use before 2018-12-31)

# Files

Read lines from a file.

import scala.io.Source
val file = Source.fromFile("path/to/file")
for (line <- file.getLines) {
    // do something
}
file.close

Write data to a text-file.

import java.io._
val file = new File("path/to/file.txt")
val buffer = new BufferedWriter(new FileWriter(file))

buffer.write("Text.")
buffer.close

# Modules

# Calendar

import java.util.Calendar
import java.text.SimpleDateFormat
val now = Calendar.getInstance.getTime      // Sun Jun 17 19:18:49 CEST 2018

Date formats.

val year = new SimpleDateFormat("yyyy")
val month = new SimpleDateFormat("M")
val day = new SimpleDateFormat("d")
val hour = new SimpleDateFormat("H")
val minute = new SimpleDateFormat("m")
year.format(now)                            // 2018
month.format(now)                           // 6
day.format(now)                             // 17
hour.format(now)                            // 19
minute.format(now)                          // 18

# Math

import scala.math._
scala.math.Pi                               // 3.141592653589793
scala.math.E                                // 2.718281828459045

Numerical operations, more at https://www.scala-lang.org/api/2.12.3/scala/math/index.html.

scala.math.abs(-20)                         // 20
scala.math.pow(2, 3)                        // 8.0
scala.math.floor(2.945)                     // 2.0
scala.math.exp(1)                           // 2.718281828459045
scala.math.sqrt(16)                         // 4.0
scala.math.sin(4 * math.Pi / 180)           // 0.0697564737441253

Rounding values.

scala.math.round(2.945)                     // 3
scala.math.round(2.495)                     // 2
scala.math.rint(2.945 * 100) / 100          // 2.94