Skip to content

Instantly share code, notes, and snippets.

@Sciss
Created March 13, 2012 19:29
Show Gist options
  • Save Sciss/2030947 to your computer and use it in GitHub Desktop.
Save Sciss/2030947 to your computer and use it in GitHub Desktop.
Compare Strings 'naturally', i.e. respecting embedded integers
def naturalCompare( a: String, b: String ) : Int = {
val asz = a.length()
val bsz = b.length()
var sz = math.min( asz, bsz )
var ai = 0
var bi = 0
while( ai < asz && bi < bsz ) {
val ac = a.charAt( ai ).toUpperCase
val bc = b.charAt( bi ).toUpperCase
if( ac.isDigit && bc.isDigit ) {
val aj = ai
while( ai < asz && a.charAt( ai ).isDigit ) { ai += 1 }
val an = a.substring( aj, ai ).toInt
val bj = bi
while( bi < bsz && b.charAt( bi ).isDigit ) { bi += 1 }
val bn = b.substring( bj, bi ).toInt
if( an < bn ) return -1 else if( an > bn ) return 1
} else {
if( ac < bc ) return -1 else if( ac > bc ) return 1
ai += 1; bi += 1
}
}
val ar = asz - ai
val br = bsz - bi
if( ar < br ) return -1 else if( ar > br ) return 1
0 // equal
}
val test = Seq( "Ch-1 1", "Ch-1 2", "Ch-1 10", "Ach-33", "666-Gaga", "Ch-12 1" )
test.sortWith( naturalCompare( _, _ ) < 0 )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment