Given is a list with (possibly) non-unique elements.
My goal is to split this list into multiple lists, in sum containing the same elements, but separated in a way that no sublist contains each element value more than once.
A few examples to show the supposed result:
[1, 2, 2] -> [[1, 2], [2]]
[1, 2, 2, 3, 3, 4, 4, 4] -> [[1, 2, 3, 4], [2, 3, 4], [4]]
[4, 4, 1, 1, 4, 1, 3, 2, 1, 2, 5, 1, 2, 4, 4, 2, 5] ->
[[4, 1, 3, 2, 5], [4, 1, 2, 5], [4, 1, 2], [4, 1, 2], [4, 1]]
The order of the elements is not important. The fact that is it preserved is just a side-effect of my current implementation, but not needed. So the following would also be valid:
[1, 2, 2] -> [[2, 1], [2]]
My current implementation looks as follows:
fun <T> ungroupDuplicateValues(values: List<T>): List<List<T>> {
val result: MutableList<List<T>> = mutableListOf()
var counts = values.groupingBy { it }.eachCount().toMutableMap()
while (counts.isNotEmpty()) {
val newCounts: MutableMap<T, Int> = mutableMapOf()
val subResult: MutableList<T> = mutableListOf()
for ((value, count) in counts) {
subResult.add(value)
if (count > 1) {
newCounts[value] = counts.getValue(value) - 1
}
}
result.add(subResult)
counts = newCounts
}
return result
}
It works, but feels kind of clumsy. Is there a more elegant/idiomatic (maybe functional) solution?