Scala: лениво сочинять итераторы - PullRequest
0 голосов
/ 27 января 2019

Предположим, у меня есть объект электронной таблицы, который состоит из строки Iterator, и каждая строка сама является итератором для ячеек.Я хочу создать функцию, которая принимает итератор электронной таблицы и возвращает итератор для ячеек.

Простейшая версия этого выглядит примерно так:

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 голосов
/ 27 января 2019

Ваш код ленивый, он просто не делает то, что вам нужно.

Во-первых, Iterator(x) не превращает x в итератор, он создает одноэлементный итератор с х как единственнымвещь.x.toIterator превращает x в итератор.

Во-вторых, вам не нужно этого делать, поскольку Iterator.map уже работает лениво и возвращает итератор (B):Iterator[B]" rel="nofollow noreferrer"> doc ).

Наконец, если вы хотите сгладить в один итератор, используйте вместо этого 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...