I have a custom class that is array<array<K>>
. I want to iterate over it with forEach
, you know, the way we do with arrays in kotlin. I implement the iterable<k>
and the hasNext
function is easy. Problem is, the next
function is hard because now I have columns and the columns are of different sizes.
I would appreciate it if you could tell me how to write next(). Some hints in the right direction is fine.
CodePudding user response:
here is an example of the next() function of an Iterable class that iterates over a 2D array in Kotlin:
class Array2DIterable<T>(val array: Array<Array<T>>) : Iterable<T> {
override fun iterator(): Iterator<T> {
return object : Iterator<T> {
var x = 0
var y = 0
override fun hasNext(): Boolean {
return x < array.size && y < array[x].size
}
override fun next(): T {
val next = array[x][y]
y
if (y >= array[x].size) {
y = 0
x
}
return next
}
}
}}
You can test it like this :
val array = arrayOf(
arrayOf(1, 2, 3),
arrayOf(4, 5, 6),
arrayOf(7, 8, 9)
)
val iterable = Array2DIterable(array)
for (element in iterable) {
println(element)
}
This is the output for this sample test case
1
2
3
4
5
6
7
8
9
Hope it'll help sort it out.
CodePudding user response:
Here is the answer to my own question. In fact, I am doing this as a self-set exercise to a tutorial about coding a hashmap.
override fun iterator(): Iterator<K> {
return object : Iterator<K> {
var stopLoopNumber = 0
var rowEntry = 0
var columnEntry = 0
override fun hasNext(): Boolean {
return stopLoopNumber < getAllEntries()
}
override fun next(): K {
//check if a row has more than one entry. if so, increment the column to output all entries in the column.
//at the same time increment the stopLoopNumber each time an entry is output.
return if (columnEntry < entries[rowEntry].size) {
stopLoopNumber
entries[rowEntry][columnEntry ].key
} else {
// the column is exhausted, so reset it to 0, ready for the next row.
columnEntry = 0
stopLoopNumber
//move to the next row and after outputting the entry, increment the column. This is vital because we must
//increment the column after an entry is output.
entries[ rowEntry][columnEntry ].key
}
}
}
}