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