Kon*_*rad 3 arrays iterator multidimensional-array kotlin
我有一个Grid
类,它是二维Cell
对象数组的包装器。我希望这个类实现Iterable<Cell>
接口,以便在循环中使用它并直接迭代整个单元格。有没有一种简单的方法可以做到这一点?Kotlin 是否支持yield return
样式迭代器?我目前的解决方案非常冗长:
override fun iterator() = object : Iterator<Cell> {
val currentOuter = grid.iterator() // grid is object of Array<Array<Cell>>
var currentInner = if (currentOuter.hasNext()) currentOuter.next().iterator() else arrayOf<Cell>().iterator()
override fun next(): Cell {
if (!hasNext()) {
throw NoSuchElementException()
}
return if (currentInner.hasNext()) {
currentInner.next()
} else {
currentInner = currentOuter.next().iterator()
currentInner.next()
}
}
override fun hasNext(): Boolean {
return currentInner.hasNext() || currentOuter.hasNext()
}
}
Run Code Online (Sandbox Code Playgroud)
Kotlin 是否支持 yield return 样式的迭代器?
是的,它是通过协程的特性实现的。这是一个独立的示例:
data class Cell(val d: Int)
val grid: Array<Array<Cell>> = arrayOf(arrayOf(Cell(1), Cell(2)), arrayOf(Cell(3), Cell(4)))
fun cellSequence() = buildSequence {
grid.forEach { it.forEach { yield(it) } }
}
fun main(args: Array<String>) {
cellSequence().forEach { println(it) }
}
Run Code Online (Sandbox Code Playgroud)
虽然这个特殊问题可以用 a 简单解决flatMap
,但所提供的代码可以作为模板来编写任何类型的程序化代码,例如:
fun complexCellSequence() = buildSequence {
yield(Cell(-1))
if (grid.size <= 2) {
yield(Cell(2))
}
for (row in grid) {
if (row.contains(Cell(1))) {
yield(Cell(1))
} else {
yield(Cell(12))
row.forEach { yield(it) }
}
}
}
Run Code Online (Sandbox Code Playgroud)
在没有协程的情况下重写这将是非常重要的。
归档时间: |
|
查看次数: |
815 次 |
最近记录: |