I have a requirement to write a generic code that perform sorting on the Seq[T]
objects. I know it won't be possible to perform sorting operation until we know the base class
and its attributes
. After taking a look into this answer I took this code and my requirement is to handle as many custom data type as possible.
case class Country(name: String, id : Int)
type CountrySorter = (Country, Country) => Boolean
def byName : CountrySorter = (c1:Country, c2:Country) => c1.name < c2.name
def byId : CountrySorter = (c1:Country, c2:Country) => (c1.id < c2.id)
val sortingMap = Map[String, CountrySorter](
"sortByCountryName" -> byName ,
"soryByCountryId" -> byId
)
Function call
def sort[T]( input : Seq[T], criteria : String) : Seq[T] = {
input.sortWith(sortingMap(criteria))
}
input.sortWith(sortingMap(criteria)) here I get error as sortWith
function only takes Country
type and not T
type.
Here's an approach if you want to define your ordering using
sortWith
:After using the above answers I have fulfilled this requirement with below code
Generic trait which is parent for all the child case classes i.e. contains only the fields on which sorting is performed
Sorting types
Sorting orders
Sorting method
A data structure to hold sorting order with a name.
Input
Output
Sorting country by using a
Map
with stringly typed keys is error prone. A better alternative is to leverage the mechanism for ordering in Scala via theOrdering[A]
type class.You can use it like this:
The catch here is to have the right ordering in scope. You can create a single ad hoc ordering in scope:
You can define the ordering in the companion of the case class and explicitly import it:
You can also use the low priority implicits trick if you have such ordering rules:
Or even explicitly pass the ordering if needed: