我正在尝试为2D数组编写迭代器。以下是我的想法。
def rowsTest() {
val array = Array(
Array(9, 11, 4, 89),
Array(7, 62, 34, 2),
Array(3, 4, 5, 12),
Array(13, 4, 5, 12),
Array(3, 24, 5, 12),
Array(3, 4, 35, 12)
)
def rows: Iterator[Iterator[Int]] = {
new Iterator[Iterator[Int]] {
private var rowIndex = 0
def hasNext: Boolean = rowIndex < 6
def next: Iterator[Int] = {
val rowIterator = new Iterator[Int] {
private var columnIndex = 0
def next: Int = {
val p = array(columnIndex)(rowIndex)
columnIndex += 1
println("ColIndex = "+ columnIndex.toString)
p
}
def hasNext: Boolean = columnIndex < 4
}
rowIndex += 1
println("RowIndex = "+ rowIndex.toString)
rowIterator
}
}
}
for(row <- rows; elem <- row)
println(elem)
}
运行时上面的代码会跳过第一行,并且在打印完所有元素时也会给出ArrayIndexOutOfBoundsException
。你能帮我弄明白我哪里出错吗?
谢谢你,
Siddharth Raina。
答案 0 :(得分:5)
以下代码怎么样?
val array = Array(Array(1,2,3),Array(4,5,6),Array(7,8,9))
array.view.flatten.iterator
在REPL中测试它是有效的。虽然我不知道我是否通过“观点”实现了我的意图。欢迎提出任何意见。
修改强>
我忘记了作者想要一个嵌套的迭代器。
array.iterator.map(_.iterator)
这当然没有“视图”而且没有开销。
答案 1 :(得分:3)
我无法从你的代码中知道你真正想做什么。
如果你想用迭代器的迭代器遍历你的数组,那么已经有了一个简单的方法:
val a2d = Array.tabulate(4,4)((i,j)=>4*i+j)
a2d.iterator.map(_.iterator)
如果你决定要一个迭代器,你也可以这样做:
a2d.iterator.flatMap(_.iterator)
如果你想遍历 columns ,即使数组按行主顺序排序,那么你还有一些工作要做(我认为这是你想要做的,但是你混淆了你的数组索引,也许还有其他一些东西):
def iterateColumns(aai: Array[Array[Int]]) = new Iterator[Iterator[Int]] {
private[this] var j = -1
private[this] val shortest = if (aai.length==0) 0 else aai.map(_.length).min
def hasNext = j+1 < shortest
def next = {
j += 1
new Iterator[Int] {
private[this] var i = -1
def hasNext = i+1 < aai.length
def next = {
i += 1
aai(i)(j)
}
}
}
}
现在你可以
scala> for (row <- a2d.iterator.map(_.iterator)) println(row.mkString(" "))
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
scala> for (col <- iterateColumns(a2d)) println(col.mkString(" "))
0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
(你也应该能够a2d.view.transpose.iterator.map(_.iterator)
来避免制作副本,但不幸的是,这看起来并不像你希望的那样2.8.1。
答案 2 :(得分:1)
如果你想以命令式的方式手工制作:
def rowsTest() {
val array = Array(
Array(9, 11, 4, 89),
Array(7, 62, 34, 2),
Array(3, 4, 5, 12),
Array(13, 4, 5, 12),
Array(3, 24, 5, 12),
Array(3, 4, 35, 12)
)
def rows: Iterator[Iterator[Int]] = {
new Iterator[Iterator[Int]] {
private var rowIndex = 0
def hasNext: Boolean = rowIndex < 6
def next: Iterator[Int] = {
// fix row index for inner iterator
val rowIdx = rowIndex
val rowIterator = new Iterator[Int] {
private var columnIndex = 0
def next: Int = {
// swap indices!!!
val p = array(rowIdx)(columnIndex)
columnIndex += 1
println("ColIndex = " + columnIndex.toString)
p
}
def hasNext: Boolean = columnIndex < 4
}
rowIndex += 1
println("RowIndex = " + rowIndex.toString)
rowIterator
}
}
}
for (row <- rows; elem <- row)
println(elem)
}
但是
val rows: Iterator[Iterator[Int]] = array.iterator.map(_.iterator)
ziggystar的仍然更好,因为它也适用于非矩形2D阵列,并且更加简洁和“scalaish”。