Given following classes:
interface Item {
val name: String
}
data class Server(override val name: String, val id: String) : Item
data class Local(override val name: String, val date: Int) : Item
data class Footer(override val name: String) : Item
If we create a list:
val items = arrayListOf<Item>()
items.add(Server("server", "b"))
items.add(Local("local", 2))
items.add(Footer("footer"))
items.add(Server("server", "a"))
items.add(Local("local", 1))
items.add(Footer("footer"))
items.add(Server("server", "c"))
items.add(Local("local", 0))
And sort it:
val groupBy = items.groupBy { it.name }
val partialSort = arrayListOf<Item>()
//individually sort each type
partialSort.addAll(groupBy["local"]!!.map { it as Local }.sortedWith(compareBy({ it.date })))
partialSort.addAll(groupBy["server"]!!.map { it as Server }.sortedWith(compareBy({ it.id })))
partialSort.addAll(groupBy["footer"]!!.map { it as Footer })
//this can be avoided if above three lines are rearranged
val fullSort = partialSort.sortedWith(compareBy({ it is Footer }, { it is Local }, { it is Server }))
Then I get a list which looks like if it was created by following commented code:
// items.add(Server("server", "a"))
// items.add(Server("server", "b"))
// items.add(Server("server", "c"))
// items.add(Local("local", 0))
// items.add(Local("local", 1))
// items.add(Local("local", 2))
// items.add(Footer("footer"))
// items.add(Footer("footer"))
Is there a better way to sort it this way? I read How to sort based on/compare multiple values in Kotlin? and Sort collection by multiple fields in Kotlin already but couldn't apply that to my code.