PfSensePuzzled - 2 months ago 8
Scala Question

# Partial Function values for sorting

I want to sort a list dependent on an external predicate. I'm looking for alternatives in Scala that are expressive. I'm not crazy about the two alternatives I've come up with. Given:

``````val lst = List(5,4,3,2,1)
val needsSorting = false
``````

I want to be able to write a concise sort expression like so:

``````lst.sortBy(sortDecision)
``````

to give me the list sorted either in ascending order:

``````List(1,2,3,4,5) // if needSorting == true
``````

or in the original chronological order

``````List(5,4,3,2,1) // if needSorting == false
``````

BUT I want the decision on HOW to sort to be embedded in my
`sortDecision`
partial function. What I've come up with are two alternatives:

Alternative 1:

``````val sortDecision: PartialFunction[Int,Int] = {
case x: Int if (needsSorting) =>  x
case _ => -1
}
``````

Alternative 2:

``````val sortDecision: PartialFunction[Int,Int] = {
case x: Int =>  if (needsSorting) x else -1
}
``````

but in both cases I have the !needsSorting case having to produce some filler (in this case -1) for the compiler to be happy. This is bad code smell. Can anyone offer an alternative to accomplish the same thing that is a bit more elegant?

I think that the more elegant way is to not sort at all if `needsSorting == false` because I think it is the only way that your intent will be completely clear.
Another way to achieve this would be to supply an `Ordering` but you'd end up having to do something similar there (such as comparing dummy values) if you want to make the decision within the `Ordering`.
You might already know that the reason that returning `-1` leaves the list unsorted is that sortBy transforms each `Int` into another value and then uses that value when comparing. So in your example it's like sorting `List(-1,-1,-1,-1,-1)` and then putting back the original values. Because scala sort is stable this leaves all the elements in the same order.