Scala:懒惰地组成迭代器

时间:2019-01-27 19:42:13

标签: scala iterator

假设我有一个电子表格对象,该对象由一个行迭代器组成,并且每一行本身都是单元格上的迭代器。我想创建一个使用电子表格迭代器并通过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]对象,然后将其转换为迭代器-这很不好。

我该如何以最小化资源使用的方式来做到这一点?我应该以某种方式使用视图吗?我该怎么办?

更一般而言,如何懒惰地构成迭代器?

1 个答案:

答案 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