I need to iterate through a list of sets in a custom order, namely with ascending cardinality. Can a iterator with custom order be created in Kotlin?
I need to iterate through a list of sets in a custom order, namely with ascending cardinality. Can a iterator with custom order be created in Kotlin?
Sure it is possible. Creating custom iterators is possible in Kotlin since... Java. You can take this code as a base:
class ListOfSets<E, S : Set<E>>(val from: List<S>) : Iterable<S> {
override fun iterator(): Iterator<S> {
return object : Iterator<S> {
val state = from.sortedBy { it.size }
var i = 0;
override fun hasNext(): Boolean = i < state.size
override fun next(): S = state[i++]
}
}
}
fun main() {
val sets = ListOfSets(
listOf(
setOf(1, 2, 3),
emptySet(),
setOf(1, 2, 3, 4),
setOf(1, 2),
setOf(1, 2, 1),
setOf(2, 2, 2, 2, 2)
)
)
for (set in sets) {
println(set)
}
}
It prints:
[]
[2]
[1, 2]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
The better question to ask yourself here is: why do you need an iterator instead of just sorting the collection with sortedBy directly where it's needed?
I think this is possible, but highly undesired due to how much internal work would have to be done inside a (in principle) lightweight abstraction of an interator.
How about creating an extension function that will give you a wrapper list that's sorted based on inner Sets' sizes, instead?
private fun <T> ArrayList<Set<T>>.sortedOnSizes(): List<Set<T>> = sortedBy {
it.size
}
fun main() {
val sets = ArrayList<Set<Int>>()
sets.add(HashSet(setOf(1, 2, 3)))
sets.add(HashSet(setOf(3)))
sets.add(HashSet(setOf(1, 2, 3, 4, 5)))
sets.sortedOnSizes().forEach(::println)
}
This prints:
[3] [1, 2, 3] [1, 2, 3, 4, 5]