The problem is the order you would like to get.
Default comparator, as well as CASE_INSENSITIVE_ORDER
comparator, follows lexicographic order. But, your expected result is not in such an order.
In lexicographic-case-insensitive order: Foo29_QA
is before foo4
. So the result is fine while using the default comparator.
So, you need to write your own comparator to apply your own logic.
val sorted3 = list.sortedWith { o1, o2 ->
// put your comparing logic here
}
Okey, so how to sort your list (this won't be an easy-peasy task).
I assume that your orders follows the pattern:
{$number_prefix}{"foo"}{$number}{"_"}{$alphanumeric_suffix}
And we would like to sort it by:
$number_prefix
DESC
$number
ASC
$alphanumeric_suffix
DESC
So, finally, we can use something like:
// create helper class for comparing
data class Element(
val originalValue: String,
val numberPrefix: Int?,
val number: Int?,
val suffix: String
)
// parse string into Element (for strings that not follow pattern
// `{$number_prefix}{"foo"}{$number}{"_"}{$alphanumeric_suffix}`
// this may throw an exception
fun parse(s: String): Element {
val normalized = s.lowercase()
val fooSplit = normalized.split("foo")
// determine numberPrefix
val numberPrefix = fooSplit.first().toIntOrNull()
// parse the rest
val suffixRest = fooSplit.last()
val suffixRestSplit = suffixRest.split("_")
// and get rest of the data
val number = suffixRestSplit.first().toIntOrNull()
val suffix = suffixRestSplit.last()
return Element(s, numberPrefix, number, suffix)
}
fun test() {
// define list
val list = mutableListOf("FOO1", "FOO2", "7foo", "FOO8", "foo5", "foo27_QA", "foo4_1", "foo29_QA", "foo5_1", "foo4")
// create a comparator with defined comparing rules
val elementComparator = compareByDescending <Element> { it.numberPrefix }
.thenBy { it.number }
.thenByDescending { it.suffix }
// and sort it with the defined comparator (map it in the fly)
val sorted = list
.map { parse(it) } // parse to helper-Element class
.sortedWith(elementComparator) // compare with our defined rules
.map { it.originalValue } // go back to original values
// prints: [7foo, FOO1, FOO2, foo4, foo4_1, foo5, foo5_1, FOO8, foo27_QA, foo29_QA]
println(sorted)
}