Loops are widely used in programming. We use them to iterate through the elements of one collection or to implement a sorting algorithm like in the following snippet:
behavior of "priority queue"
it should "be implemented naively with a for loop and ordering" in {
def addLetter(letter: String, data: List[String]): List[String] = {
var wasSplitted = false
var splitIndex = -1
for (index <- 0 until data.length if !wasSplitted) {
val letterFromData = data(index)
if (letter > letterFromData) {
wasSplitted = true
splitIndex = index
}
}
val (splittedListBeginning, splittedListEnd) = data.splitAt(splitIndex)
val prioritizedList = splittedListBeginning ++ List(letter) ++ splittedListEnd
prioritizedList
}
val prioritizedList = addLetter("A", List.empty)
val prioritizedListWithD = addLetter("D", prioritizedList)
val prioritizedListWithB = addLetter("B", prioritizedListWithD)
prioritizedListWithB should have size 3
prioritizedListWithB should contain inOrder("D", "B", "A")
}
However, Scala comes the data structure able to implement this sorting behavior without a loop. This structure is called PriorityQueue and below you can find an example:
it should "use built-in data structure" in {
val priorityLetters = new scala.collection.mutable.PriorityQueue[String]()
priorityLetters.enqueue("A")
priorityLetters.enqueue("D")
priorityLetters.enqueue("B")
priorityLetters should have size 3
priorityLetters.dequeueAll should contain inOrder("D", "B", "A")
}
it should "use built-in data structure with custom ordering" in {
case class Customer(businessValue: Int)
//def compareCustomers(customers: (Customer, Customer)): Int = customers._1.businessValue > customers._2.businessValue
//val customerOrdering: Ordering[Customer] = Ordering.by(customer => customer.businessValue)
def getCustomerOrder(customer: Customer): Int = customer.businessValue
val customers = new scala.collection.mutable.PriorityQueue[Customer]()(Ordering.by(getCustomerOrder))
customers.enqueue(Customer(1))
customers.enqueue(Customer(100))
customers.enqueue(Customer(50))
customers should have size 3
customers.dequeueAll should contain inOrder(Customer(100), Customer(50), Customer(1))
}