在Kotlin中展开二维数组的迭代器

我有一个Grid类,包装在Cell对象的二维数组。 我希望这个类实现Iterable接口,以便在循环中使用它并直接遍历整个单元格。 有一个简单的方法来做到这一点? Kotlin是否支持yield return样式迭代器? 我目前的解决方案是相当冗长的:

 override fun iterator() = object : Iterator { val currentOuter = grid.iterator() // grid is object of Array<Array> var currentInner = if (currentOuter.hasNext()) currentOuter.next().iterator() else arrayOf().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() } } 

一个非常简单的解决方案就是这样的:

 val grid: Array> = ... override fun iterator() : Iterator = grid.flatMap { it.asList() }.iterator() 

Kotlin是否支持yield return样式迭代器?

是的,它通过协程的function。 这是一个独立的例子:

 data class Cell(val d: Int) val grid: Array> = arrayOf(arrayOf(Cell(1), Cell(2)), arrayOf(Cell(3), Cell(4))) fun cellSequence() = buildSequence { grid.forEach { it.forEach { yield(it) } } } fun main(args: Array) { cellSequence().forEach { println(it) } } 

虽然这个问题本来可以简单地用flatMap解决,但是所提供的代码可以作为一个模板来编写任何types的程序代码,例如:

 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) } } } } 

如果没有协程,这将是相当不重要的。