假设我有一个电子表格对象,该对象由一个行迭代器组成,并且每一行本身都是单元格上的迭代器。我想创建一个使用电子表格迭代器并通过Cells返回迭代器的函数。
最简单的版本是这样的:
val sheet: Iterable[Row] = //some way of getting the sheet.
case class SheetCell(rowIndex: Int, colIndex: Int, value: Any)
val itr = Iterator(sheet map {row: Row =>
row map {cell: Cell => SheetCell(row.getRowNum, cell.getColumnIndex, cell)}
})
但是,我也想这样做。即而不实际将整个电子表格读入内存或实际遍历行/单元格迭代器,我的理解是上述代码并不是很懒。我很确定它会遍历行/单元迭代器,并在内存中建立一个List[SheetCell]
对象,然后将其转换为迭代器-这很不好。
我该如何以最小化资源使用的方式来做到这一点?我应该以某种方式使用视图吗?我该怎么办?
更一般而言,如何懒惰地构成迭代器?
答案 0 :(得分:3)
您的代码是惰性的,只是没有执行您想要的操作。
首先,Iterator(x)
不会将x变成迭代器,它会创建一个以x为唯一元素的单元素迭代器。 x.toIterator
将x变成一个迭代器。
第二,您不需要这样做,因为Iterator.map
已经很懒惰了,可以返回Iterator(doc)。
最后,如果要展平为单个Iterator,请改用flatMap:
sheet.flatMap { row =>
row.map { cell => SheetCell(row.getRowNum, cell.getColumnIndex, cell) }
}
或者,带有理解力:
for (row <- sheet; cell <- row) yield
SheetCell(row.getRowNum, cell.getColumnIndex, cell)
如果您只想使用Iterator[Cell]
,则可以执行sheet.flatten
。