val title = "Jurassic Park"
val runtime = 12345
val is3d = false
val role = ("Sam Neil", "Dr. Alan Grant")
var rating = 0.8
rating = 0.9
val title: String = "Jurassic Park"
val runtime: Int = 12345
val is3d: Boolean = false
val role: (String, String) = ("Sam Neil", "Dr. Alan Grant")
var rating: Double = 0.8
rating = 0.9
def success(budget: Int, gross: Int) =
budget < gross
val r = success(100, 200)
r == true
def success(budget: Int,
gross: Int): Boolean =
budget < gross
val r = success(100, 200)
r == true
def success(budget: Int,
gross: Int) = {
budget < gross
}
val r = success(100, 200)
r == true
if ( expr ) a else if( expr ) b else c
def simpleRating(rating: Double) =
if(rating > 8.0) "Excellent"
else if(rating > 4.0) "Okay"
else "Poor"
val s = simpleRating(5.0)
s == Okay
def success(budget: Int,
gross: Int = 50) =
budget < gross
val r = success(100)
r == false
val r = success(100, 200)
r == true
def success(budget: Int = 50,
gross: Int = 50) =
budget < gross
val r = success(budget = 100)
r == false
class Actor(firstName: String,
surname: String)
val tom = new Actor("Tom", "Hanks")
class Actor(firstName: String,
surname: String)
val tom = new Actor("Tom", "Hanks")
tom.name
class Actor(firstName: String,
surname: String) {
val name = firstName + " " + surname
}
val tom = new Actor("Tom", "Hanks")
p.name
class Actor(firstName: String,
surname: String) {
def name = firstName + " " + surname
}
val tom = new Actor("Tom", "Hanks")
p.name
case class Actor(firstName: String,
surname: String)
val tom = new Actor("Tom", "Hanks")
val tom2 = tom.copy(surname = "Cruise")
tom2.surname == "Cruise"
val m = Movie(certificate = "U")
val ageRequirement = p match {
case Movie("U" | "PG") => 0
case Movie("12A") => 18
case Movie(cert) => cert.toInt
}
the AND operator is &&
case class Actor(name: String) {
def +(other: Actor) =
Actor(name + other.name)
}
Actor("Brad").+(Actor("Angelina"))
Actor("Brad") +(Actor("Angelina"))
Actor("Brad") + Actor("Angelina")
(args) => body
val funky = (args) => body
val success = (budget: Int, gross: Int) =>
budget < gross
val r = success(100, 200)
val r = success.apply(100, 200)
case class Movie(name: String, rating: Float)
val kb = Movie("Kill Bill", rating = 8.2)
val tr = Movie("The Room", rating = 3.5)
> greatFilm(kb) == true
> greatFilm(tr) == false
Write the function greatFilm
. It checks the rating
is >= 7.0
val success =
(budget: Int, gross: Int) => budget < gross
val success: (Int, Int) => Boolean =
(budget, gross) => budget < gross
val success: (Int, Int) => Boolean =
_ < _
val movies = List(
Movie("Jurassic Park", 10.0f),
Movie("The Room", 3.5f),
Movie("Home Alone", 7.4f)
)
movies: List[Movie] = List(Movie(...
val movies =
Movie("Jurassic Park", 10.0f) ::
Movie("The Room", 3.5f) ::
Movie("Home Alone", 7.4f) :: Nil
movies: List[Movie] = List(Movie(...
movies.count(greatFilm)
2
movies.count(_.name.length > 10)
1
movies.filter(greatFilm)
List( Movie(Jurassic Park,10.0), Movie(Home Alone,7.4))
movies.filter(_.name.contains("J"))
List(Movie(Jurassic Park,10.0))
movies.map(greatFilm)
List(true, false, true)
movies.map(_.name)
res: List[String] = List( Jurassic Park, The Room, Home Alone)
movies.collect {
case Movie(name, rating) if rating < 4 => name
}
res: List[String] = List(The Room)
val actor = List("Tom", "Val", "Anthony")
val chars = List("Maverick", "Iceman", "Goose")
actor zip chars
res15: List[(String, String)] = List( (Tom,Maverick), (Val,Iceman), (Anthony,Goose))
case class Movie(genre: String, gross: Int)
val movies = (100 to 5000 by 50).flatMap(g =>
Movie("Drama", g) :: Movie("Romcom", g) ::
Movie("Action", g) :: Nil)
movies
You can call .sum
on a List[Int]
to get a total
val res = movies.
filter(_.genre == "Action").
map(_.gross).
sum
val res = movies.collect {
case Movie("Action", gross) => gross
}.sum
movies.map (movie =>
if(movie.score < 4) "Flop"
else "Blockbuster"
)
movies.collect {
case movie if movie.score < 4 => "Flop"
}
movies.map (movie =>
if(movie.score < 4) "Flop"
else "Blockbuster"
)
movies.collect {
case movie if movie.score < 4 => "Flop"
case _ => "Blockbuster"
}
movies.map (movie =>
if(movie.score < 4) "Flop"
else "Blockbuster"
)
movies.map {
case movie if movie.score < 4 => "Flop"
case _ => "Blockbuster"
}
val f: Int => String = {
case 0 => "zero!"
case 1 => "one!"
}
What happens if we call this with the argument 3?
Option[T]
type is used to represent optional datacase class Some(val x)
case object None
val sort = Some("newest")
val sort = None
val sort = Option("newest")
val sort = Option(null)
val sort: Option[String] = …
sort.getOrElse("newest")
val querySort: Option[String] = …
val headerSort: Option[String] = …
> val token = querySort.orElse(headerSort)
Some("newest")
val sort: Option[String] = …
val movies = sort
.map(sort => getMoviesFromDb(sort))
page = Some(List(Movie(...), Movie(...)))
page = None
Rating(3, None).asString
"5* [no comment]"
Rating(1, Some("So awful")).asString
"1* [comment: So awful]"
def asString =
stars + "* " +
comment.map("[comment:" + _ + "]").
getOrElse("[no comment]")
def asString =
stars + "* " + (
if(comment.nonEmpty) "[comment:" + comment.get + "]"
else "[no comment]")
def asString = stars + "* " + (comment match {
case Some(c) => s"[comment:$c]"
case None => "[no comment]"
})
val spielbergCast = movies.collect {
case Movie("Spielberg", cast) =>
cast.map(_.name)
}
.flatten
val spielbergCast = for {
movie <- movies
if movie.director.name == "Spielberg"
actor <- movie.cast
} yield actor.name
case class Award(name: String,
outcome: String)
// outcome is "Won" or "Nominated"
trait Person {
def awards: List[Award]
def awardsWon =
prods.filter(_.outcome == "Won")
}
case class Actor(awards: List[Award])
extends Person
val seanBean = Actor(
Award("Best Lead Actor", "Won") :: Nil
)
seanBean.awardsWon.size == 1
case class Director(awards: List[Award])
val spielberg = new Director(
Award("Best Film", "Won") :: Nil
) with Person
spielberg.awardsWon.size == 0
Production
with and abstract def releaseYear
of type Int
Film
class; extends Production implement releaseYear with a year valTvShow
to extends Production
case class Series(year: Int)
case class TvShow(series: List[Series])
trait Production { def releaseYear: Int }
case class Film(releaseYear: Int) extends Production
case class TvShow(series: List[Series]) {
def releaseYear = series.sortBy(_.year).head.year
}
val thirtyRock = new TvShow(
Series(2011) :: Series(2012) :: Nil
) with Production
thirtyRock.releaseYear
res2: Int = 2011
object Counties {
val countries = "GB" :: "ZH" :: Nil
def supported(c: String) =
countries.contains(c)
}
> Countries.supported("ZH")
> true
case class Movie(name: String)
object Movie {
def apply(name: String) =
new Movie(name)
}
> Movie("Jurassic Park")
sealed trait Outcome
case object Nominated extends Outcome
case object Won extends Outcome
case class Award(outcome: Outcome)
val award = Award(Won)
val msg = award match {
case Award(Won) => "Woohoo!"
case Award(_) => "Unlucky"
}
implicit
keyword can be used:val
- implicit parameterscase class HttpRequest (
headers: List[HttpHeader]
)
case class HttpHeader (
name: String, value: String
)
implicit class PimpedHttpRequest(r: HttpRequest) {
def headerValue(name: String) =
r.headers.find(_.name == name)
}
val request = HttpRequest(…)
request.headerValue("page")
// Compiler generates
// PimpedHttpRequest(request).headerValue("page")
case class Duration(mins: Int, secs: Int)
Duration(1, 30).totalSecs == 90
implicit class PimpedDuration(d: Duration) {
def totalSecs = d.mins * 60 + d.secs
}
Duration(1, 30).totalSecs == 90
Seq(22, 2, 11, 1).sorted
// Seq(1, 2, 11, 22)
Seq("22", "2", "11", "1").sorted
// Seq(1, 11, 2, 22)
trait Seq[A] {
def sorted[A](implicit ord: Ordering[A]): Seq[A]
}
case class Film(year: Int)
implicit val filmOrd = new Ordering[Film] {
def compare(x: Film, y: Film) =
x.year.compareTo(y.year)
}
val films = Seq(Film(2011), Film(1960), Film(1994))
films.sorted
// List(Film(1960), Film(1994), Film(2011))
trait Seq[A] {
def sorted[A](asc: Boolean)
(implicit ord: Ordering[A]): Seq[A]
}
val films = Seq(Film(2011), Film(1960), Film(1994))
films.sorted(false)
implicit val movieOrd = new Ordering[Film] {
def compare(x: Film, y: Film) =
x.year.compareTo(y.year)
}
implicit object FilmOrd extends Ordering[Film] {
def compare(x: Film, y: Film) =
x.year.compareTo(y.year)
}