I have an array of objects (Drinks
) that contains a theDrinkName
field. I would like to be able to sort the Drink
objects theDrinkName
field alphabetically first, and then numerically.
Here's the function that I use to generate all drinks.
data class Drink(val theDrinkName:String)
object DrinkData {
fun generateAllDrinks():Array<Drink> {
return arrayOf(
Drink("Vodka"),
Drink("rum"),
Drink("Gin"),
Drink("151"),
Drink("99")
)
}
}
And I sort it alphabetically (based on theDrinkName
) with the following:
val allDrinks = DrinkData.generateAllDrinks().sortedBy { it.theDrinkName.toLowerCase().first()}.toTypedArray()
for (drink in allDrinks){
println(drink.theDrinkName)
}
This prints the following:
151
99
Gin
rum
Vodka
By default it sorts numbers first, and then by letters. How do I sort this data by letters first, and then numbers, as seen below:
Desired result:
Gin
rum
Vodka
151
99
CodePudding user response:
You can sort first by the indication whether the fist char is a digit and then by the full name:
val allDrinks = DrinkData.generateAllDrinks().sortedWith(
compareBy<Drink> { it.theDrinkName.first().isDigit() }
.thenBy { it.theDrinkName.lowercase() }
)
CodePudding user response:
Another possible solution:
The reason you are getting numbers before the words is because alphabets have larger ASCII value than digits. You can add a space before words to lower their comparison value and use that for sorting.
DrinkData.generateAllDrinks().sortedBy { drink ->
drink.theDrinkName.lowercase().let { if (it[0].isDigit()) it else " $it" }
}