Christian Schmitt
Christian Schmitt

Reputation: 892

Natural/Human Ordering String (Case Class with String)

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

Answers (2)

jazmit
jazmit

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

melps
melps

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

Related Questions