I have an unsorted List of Users and a sorted list of Users id. Id is a string. I want to sort first list by second. How to do that in Kotlin?
data class User(val name : String, val id : String)
val unsorted = listOf<User>(
User("Max", "b12s11"),
User("Joe", "dj1232"),
User("Sam", "23d112"),
User("Tom", "k213i1")
)
val sorted = listOf<String>(
"dj1232",
"b12s11",
"k213i1",
"23d112"
)
// what I need
val result = listOf<User>(
User("Joe", "dj1232"),
User("Max", "b12s11"),
User("Tom", "k213i1"),
User("Sam", "23d112")
)
Shorter solution:
val result = unsorted.sortedBy { sorted.indexOf(it.id) }
Although the other answers show a solution to your problem, it seems to me that a Map<String, User>
might better fit the purpose, e.g.:
val usersByid = unsorted.associateBy { it.id }
val result = sorted.mapNotNull {
usersById[it]
}
I assume that every id is only once in the list, therefore I used associateBy
. Otherwise it wouldn't be an id for me ;-)
The main difference between this solution and others is that this solution only returns the entries that are also in the sorted
-list. Note that if you have users for which you have no id in the sorted
-list, this solution omits them, whereas other solutions put those entries at the front of the list. Depends on what you really want.
It could be that this solution is more efficient than the others. Accessing the Map
should be much faster then reiterating all the entries over and over again (which both indexOf
and first
basically do).
I don't know of any Kotlin syntax for doing this, sorting one list by another, but this solution should work for you (the way I understood this question, was that you want to sort according to the Id's in sorted
):
val correctList = arrayListOf<User>()
sorted.forEach { sortedId ->
correctList.add(unsorted.first {
it.id == sortedId
})
}
It iterates over your sorted list of Id's and takes the item in the first list (unsorted) which matches that ID and adds it to correctList
Edit: see answer from @Andrei Tanana for a better kotlin answer than mine : sort unsorted collection with another sorted collection's field it's pretty cool :D
Edit2: Thanks to @Roland for pointing out, I can simplify my answer even further with :
val correctList = sorted.map { sortedId -> unsorted.first { it.id == sortedId } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With