Recently I was pairing with a co-worker on a new view for our application. The purpose of this view was just to show a timeline of all activities (regardless of type) occurring in the system. We were confident there would be a way to accomplish this task easily in Scala!
For this example lets say we are writing a program for a car dealership. The manager of the dealership would like a page showing test drives and sales throughout the day. The point of this page is not to connect test drives to sales, but instead a view used to give a timeline of the activity taking place on the car lot.
In the example below, even though we have two lists of different types testDrives=List[TestDrives] and purchases=List[Purchases], they both have a common field which is “date“. To do the sort we first combine the two lists with (testDrives ::: purchases), creating a new list of type List[{def date: Date}]. The objects in the new list all have “date“. So now sorting the list is easy!
import scala.collection.JavaConversions._
import java.util.Date
case class TestDrive(car: String, priceQuoted: Int, date: Date)
case class Purchase(car: String, priceSold: Int, date: Date)
val date = new Date
val dateFormat = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
val testDrives = List(TestDrive("Charger", 22000, new Date(date.getTime - 1000000)), TestDrive("Camero", 250000, new Date(date.getTime - 4000000)), TestDrive("Pony", 2500, new Date(date.getTime - 10000000)))
val purchases = List(Purchase("Infiniti G35x", 19500, new Date(date.getTime - 500000)), Purchase("Infiniti G37x", 28500, new Date(date.getTime - 6000000)), Purchase("Altima", 35000, new Date(date.getTime - 9000000)))
// Combine the TestDrives and Purchases lists and sort descending by date
for (something <- (testDrives ::: purchases).asInstanceOf[List[{def date: Date}]].sortBy(_.date).reverse) {
// Now if we want to show fields other than "date", we can easily check the type of each object, and cast it appropriately
if (something.isInstanceOf[TestDrive]) {
val testDrive = something.asInstanceOf[TestDrive]
println("Test Drive: %s\tQuoted price: %d \t Date: %s".format(testDrive.car, testDrive.priceQuoted, dateFormat.format(testDrive.date)))
}
else {
val purchase = something.asInstanceOf[Purchase]
println("Purchase: %s\tSold price: %d \t Date: %s".format(purchase.car, purchase.priceSold, dateFormat.format(purchase.date)))
}
}
The program creates the following output, all test drives and purchases combined into a single timeline sorted descending by date.
>scala example.scala Purchase: Infiniti G35x Sold price: 19500 Date: 2011/12/23 14:48:41 Test Drive: Charger Quoted price: 22000 Date: 2011/12/23 14:40:21 Test Drive: Camero Quoted price: 250000 Date: 2011/12/23 13:50:21 Purchase: Infiniti G37x Sold price: 28500 Date: 2011/12/23 13:17:01 Purchase: Altima Sold price: 35000 Date: 2011/12/23 12:27:01 Test Drive: Pony Quoted price: 2500 Date: 2011/12/23 12:10:21
That is all!