Reputation: 892
Currently I have a case class which has a Text field with the following contents:
2 AT 30%
2 AT 40%
2 AT 50%
5 AT 30%
5 AT 40%
5 AT 50%
10 AT 30%
10 AT 40%
11 AT 30%
12 AT 30%
Currently they are unordered so that 5 AT will be before 2 AT and so on.. is there a easy way to order them naturally or do I need to have something like that:
object ExtraCostOrdering extends Ordering[[ExtraCost] {
override def compare(x: List[ExtraCost], y: List[ExtraCost]): Int = {
}
}
And how do I do that correctly?
It should sort naturally so that 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 and not 11, 12, 2, 3, 4 Mostly text fields with numbers sorting is wrong.
Edit: Sometimes the List could contain Strings without any number at all so
5 AT 50%
10 AT 30%
10 AT 40%
I'm a String
is valid, too.
Upvotes: 2
Views: 887
Reputation: 5410
AFAIK a natural sort order isn't built into Scala. However, you can simulate it easily by converting to integer types:
Given the following definitions...
def asNatural(row: String) = row.split(" ").head.toInt
val myList = List("5 AT 30%","12 AT 30%", "2 AT 40%", "5 AT 50%", "5 AT 40%")
...you can use sortBy
to do a natural sort.
scala> myList.sortBy(asNatural)
res2: List[String] = List(2 AT 40%, 5 AT 30%, 5 AT 50%, 5 AT 40%, 12 AT 30%)
Of course, the above would fail if you have any poorly formatted strings coming in. The following is slightly more 'production-ready', and will put all badly formatted strings to the end:
import scala.util.Try
def asNatural(row: String) =
row.split(" ").headOption
.flatMap{ head => Try(head.toInt).toOption }
.getOrElse(Integer.MAX_VALUE)
Upvotes: 3
Reputation: 1247
Since the ordering you want is standard you could just do something like:
val sorted: List[ExtraCost] = unsorted.sortWith((a,b) => a.textField > b.textField)
Upvotes: -2