Skip to content

Instantly share code, notes, and snippets.

@jehrhardt
Created August 31, 2015 09:33
Show Gist options
  • Save jehrhardt/eb81b686a1ad8469f619 to your computer and use it in GitHub Desktop.
Save jehrhardt/eb81b686a1ad8469f619 to your computer and use it in GitHub Desktop.

Collections

Introduction to collection API

Option

There are Some and None

val i = Some(1)
val j = None

def orZero(number: Option[Int]): Int = {
  if(!number.isEmpty) { // better number.isDefined and best number.getOrElse(0)
    number.get
  } else {
    0
  }
}

orZero(j)

getOrElse is call by name!

Pattern matching

Call match and do pattern matching and remove the braces!

def orZero(number: Option[Int]): Int = number match {
  case Some(1) => 1
  case None => 0
}

def orZero(number: Option[Int]): Int = number match {
  case Some(n) => n
  case None => 0
}

def orZero(number: Option[Int]): Int = number match {
  case Some(n) => n
  case _ => 0
}

def orZero(number: Option[Int]): Int = number match {
  case Some(n) if n > 0 => n + 1
  case Some(n) => n
  case _ => 0
}

Null safe programming

Call map

def addOneWhenDefined(number: Option[Int]): Option[Int] = {
  number.map((x: Int) => x + 1)  z
}  def addOneWhenDefined(number: Option[Int]) = number map (_ + 1)

orZero(addOneWhenDefined(i))
orZero(addOneWhenDefined(j))

Use curly braces and infix notation to make map look like previous match call.

def addOneOrMoreWhenDefined(number: Option[Int]) = number map {
  x => x + 1
}

Pattern matching works also with map

def addOneWhenDefinedAndLowerFive(number: Option[Int]) = number map {
  case x if x < 5 => x + 1
  case _ => 0
}

orZero(addOneWhenDefinedAndLowerFive(i))
orZero(addOneWhenDefinedAndLowerFive(j))
orZero(addOn  eWhenDefinedAndLowerFive(Some(5)))

Collection types

There are Sequences, Sets, Arrays and Maps

Seq(1, 2, 3)
Set(1, 2, 3)  Set(1, 2, 3, 3)

Array(1, 2, 3)
val foo = "Hello world".getBytes(StandardCharsets.UTF_8)
val foo: Seq[Byte] = "Hello world".getBytes(StandardCharsets.UTF_8)

("Hello", "world")
Map(("h", "Hello"), ("w", "world"))  Map("h" -> "Hello", "w" -> "world")

Mutable versions with prefix.

Collection methods

map, flatMap, flatten, zip, mkstring, reduce

Seq(1, 2, 3) map (_.toString)

Seq("Hello world", "foo bar") flatMap (_ split "\\W+")

Seq(Seq(1, 2), Seq(3)) flatten

Seq(Some(1), Some(2), None, Some(3)) flatten

Seq(1, 2) zip Seq(3, 4)

Seq("hello", "world").mkString(", ")

Seq(1, 2, 3) reduce (_ + _)

Add elements and understand Nil

Seq(1) :+ 2
2 +: Seq(1)

Nil :+ 1 :+ 2 :+ 3

Pattern matching

def sum(numbers: Seq[Int]): Int = numbers match {
  case Nil => 0
  case head :: tail => head + sum(tail)
}

sum(Seq(1, 2, 3))

Compile error mit @tailrec

def sum(numbers: Seq[Int]): Int = {
  @tailrec
  def innerSum(current: Int, n: Seq[Int]): Int = n match {
    case Nil => current
    case head :: tail => innerSum(current + head, tail)
  }

  innerSum(0, numbers)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment