Jun 22, 2018 ▪ 21 min read (~3 pages) Computer Science

A Scala Primer and Cheat Sheet

1. Introduction

Scala program structure (build and run with $scalac <filename>.scala && scala <filename>). object Main { // do something def main(args: Array[String]) { // do something } }  Handling exceptions. try { // do something } catch { case a: ArithmeticException => println("This is an arithmetic error: " + a) case b: Throwable => println("Error: " + b) } finally { // do something }  Build and run in Sublime Text (build system). { "cmd": ["scala", "$file"],
"path": "\$PATH:/usr/local/bin",
"file_regex": "^(.+):(\\d+): .+: (.+)",
"selector": "source.scala"
}


2. Arithmetic Operators

Basic 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


Be aware of this common division error.

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


Modulo (remainder).

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


3. Variables

Use val keyword to make data immutable.

val x: Int = 6
val y: String = "String"
val z: Double = 1.05

x, y, z
// (6,String,1.05)


Use getClass.getSimpleName to get type.

x.getClass.getSimpleName
// int
y.getClass.getSimpleName
// String
z.getClass.getSimpleName
// double


Use var keyword to make data 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"


4. Strings

4.1 Indexing

val string: String = "proton"


Use charAt and slice to index and slice string.

string.charAt(0)
// p
string.slice(0,4)
// prot


Length of string.

string.length
// 6


Index and slice using substring.

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


4.2 Operations

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 string

val string: String = "    some text    "

string.trim
// some text


5. Data structures

5.1 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 new list by adding item 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)
// 200
list_two.last
// List(1.0, 0.0)

list_range.filter(_ > 5)
// List(6, 7, 8, 9)

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


Create list from a string

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


5.2 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 values in tuple to variables

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

first
// Alpha
second
// Beta
third
// Gamma


5.3 Maps

Maps are key-value pairs and immutable.

val map_any = Map("Adam" -> List("[email protected]", 2445055),
"Bard" -> "[email protected]" )

map_any("Adam")
// List([email protected], 2445055)

map_any.contains("Bard")
// true
map_any.exists(_ == "Bard" -> "[email protected]")
// true


Using collection.mutable.Map for mutable maps.

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)


5.4 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


Using collection.mutable.Set for mutable sets.

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 (using clone to copy).

val A = set_mutable_one.clone
val B = set_mutable_two.clone

A | B
// Set(9, 1, 5, 3, 7) 		(Union)
A & B
// Set(5) 					(Intersection)
A &~ B
// Set(1, 3) 				(Difference)

A union B
// Set(9, 1, 5, 3, 7)
A intersect B
// Set(5)
A diff B
// Set(1, 3)


Subsets.

A subsetOf B
// false


6. Conditionals

6.1 If-Else

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
}


6.2 Logical Operators

Booleans.

val T: Boolean = true
val F: Boolean = false

T || F
// true
T && (T && F)
// false
!T
// false
!(!T)
// true


Numbers.

1 == 2
// false
1 != 2
// true


7. Loops

7.1 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 ((key, value) <- map) {
println(key, value)
// (Alpha,1) (Beta,2)
}


7.2 While

var a = 0
var b = 5

while (a < b) {
// do something
a += 1
}

println(a)
// 5


8. Functions

Functions are defined with def keyword.

def fun(): 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 for fun.
*
*  @param arg an argument
*/
def fun(arg:Any) = {
// do something
}


9. Classes

Classes are defined with class keyword.

class Money(val a:Int, val c:String) {
var amount: Int = a
var currency: String = c

override def toString = amount.toString ++ " " ++ currency
}


Create new instance of class.

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

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


Print use toString.

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)


10. Files

Use io.Source to read and write to files.

import scala.io.Source


val file = Source.fromFile("path/to/file")

for (line <- file.getLines) {
// do something
}


Use close to close file.

file.close


Write to text-file (using Java io).

import java.io._

val file = new File("path/to/file.txt")

val buffer = new BufferedWriter(new FileWriter(file))

buffer.write("Text.")

buffer.close


11. Modules

11.1 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


11.2 Math

import scala.math._

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


Mathematical operations.

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.abs(-20)
// 20

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