Skip to content

Instantly share code, notes, and snippets.

@amast09
Last active July 30, 2017 21:58
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Advanced Scala for comprehensions
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
import java.util.Calendar
case class Movie(name: String, year: Int, rating: BigDecimal, directorId: Int)
case class Director(id: Int, name: String, yearBorn: Int)
def getMoviesByRating(rating: BigDecimal): Future[Seq[Movie]] = {
val fakeDbOfMovies = Seq(
Movie("The Shawshank Redemption", 1994, 9.2, 1),
Movie("The Godfather", 1972, 9.2, 2),
Movie("The Godfather: Part II", 1974, 9.0, 2),
Movie("The Dark Knight", 2008, 9.0, 3),
Movie("12 Angry Men", 1957, 8.9, 4),
Movie("Schindler's List", 1993, 8.9, 5),
Movie("Pulp Fiction", 1994, 8.9, 6),
Movie("The Lord of the Rings: The Return of the King", 2003, 8.9, 7),
Movie("The Good, the Bad, and the Ugly", 1966, 8.9, 8),
Movie("Fight Club", 1999, 8.8, 9)
)
Future.successful(fakeDbOfMovies.filter(_.rating == rating))
}
def getDirector(directorId: Int): Future[Option[Director]] = {
val fakeDbOfDirectors = Seq(
Director(1, "Frank Darabont", 1959),
Director(2, "Francis Ford Coppola", 1939),
Director(3, "Christopher Nolan", 1970),
Director(4, "Sidney Lumet", 1924),
Director(5, "Steven Spielberg", 1946),
Director(6, "Quentin Tarantino", 1963),
Director(7, "Peter Jackson", 1961),
Director(8, "Sergio Leone", 1929),
Director(9, "David Fincher", 1962),
)
Future.successful(fakeDbOfDirectors.find(_.id == directorId))
}
def getAverageAgeOfDirectorForRatingNested(rating: BigDecimal): Future[Int] = {
val currentYear = Calendar.getInstance().get(Calendar.YEAR)
getMoviesByRating(rating).flatMap(moviesWithRating => {
val directorAgesForRating = moviesWithRating.map(director => {
getDirector(director.directorId).map(maybeDirector => {
maybeDirector.map(director => {
currentYear - director.yearBorn
})
})
})
Future.sequence(directorAgesForRating).map(_.flatten[Int].sum / directorAgesForRating.length)
})
}
def getAverageAgeOfDirectorForRating(rating: BigDecimal): Future[Int] = {
val currentYear = Calendar.getInstance().get(Calendar.YEAR)
for {
moviesWithRating <- getMoviesByRating(rating)
directorIdsForRating <- Future.successful(moviesWithRating.map(_.directorId))
maybeDirectors <- Future.sequence(directorIdsForRating.map(getDirector))
directors <- Future.successful(maybeDirectors.flatten[Director])
directorBirthYears <- Future.successful(directors.map(_.yearBorn))
directorAges <- Future.successful(directorBirthYears.map(currentYear - _))
averageDirectorAge <- Future.successful(directorAges.sum / directors.length)
} yield averageDirectorAge
}
val averageAge1 = Await.result(getAverageAgeOfDirectorForRatingNested(8.9), atMost = 5.seconds)
val averageAge2 = Await.result(getAverageAgeOfDirectorForRating(8.9), atMost = 5.seconds)
println(averageAge1)
println(averageAge2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment