Friday, August 19, 2011

Natural Sorting...

A natural sort implementation using scala :

implicit val ord = new Ordering[String] {
  def groupIt(str:String) = 
       if (str.nonEmpty && str.head.isDigit) str.takeWhile(_.isDigit)
       else str.takeWhile(!_.isDigit)
  val dec="""(\d+)"""r
  def compare(str1: String, str2: String) = {
    (groupIt(str1), groupIt(str2)) match {
      case ("","") => 0
      case (dec(x),dec(y)) if (x.toInt==y.toInt) =>  
         compare(str1.substring(x.size), str2.substring(y.size))
      case (dec(x),dec(y)) => (x.toInt - y.toInt)
      case (x,y) if (x == y) =>
         compare(str1.substring(x.size), str2.substring(y.size))
      case (x,y) => x compareTo y
    }
  }
}


And now a usage case :

test("basic tests") {
  import scala.collection.immutable.TreeSet

  val t0 = new TreeSet[String]() ++ List("10", "5", "1")
  t0.toList should equal (List("1", "5", "10"))

  val t1 = new TreeSet[String]() ++ List("a-100","a-10", "a-5", "a-1")
  t1.toList should equal (List("a-1", "a-5", "a-10", "a-100"))
}


Of course it doesn't manage floating numbers, "1.01", will be sorted as "1.1"... or "a-2-050" will appear after "a-2-25".

CONTEXT : Linux Gentoo / Scala 2.9.0 / Java 1.6.0_26

0 commentaires:

Post a Comment