Scala: сгруппировать Iterable в Iterable of Iterables с помощью предиката

У меня есть очень большие итераторы, которые я хочу разбить на части. У меня есть предикат, который смотрит на элемент и возвращает истину, если это начало новой части. Мне нужно, чтобы части были итераторами, потому что даже части не помещаются в память. Так много кусков, что я бы опасался рекурсивного решения, взорвавшего ваш стек.Ситуация похожа на этот вопрос , но мне нужны итераторы вместо списков, а «часовые» (элементы, для которых предикат истинен) появляются (и должны быть включены) в начале фрагмента. Полученные итераторы будут использоваться только по порядку, хотя некоторые из них могут вообще не использоваться, и они должны использовать только память O (1). Я полагаю, это означает, что все они должны использовать один и тот же базовый итератор. Производительность важна.

Если бы я попытался ударить по сигнатуре функции, это было бы так:

def groupby[T](iter: Iterator[T])(startsGroup: T => Boolean): Iterator[Iterator[T]] = ...

Я бы с удовольствием использовал takeWhile , но он теряет последний элемент. Я исследовал диапазон , но он буферизует результаты. Моя текущая лучшая идея включает BufferedIterator , но, возможно, есть способ получше.

Вы будете знать, что сделали все правильно, потому что что-то вроде этого не приведет к сбою вашей JVM:

groupby((1 to Int.MaxValue).iterator)(_ % (Int.MaxValue / 2) == 0).foreach(group => println(group.sum))
groupby((1 to Int.MaxValue).iterator)(_ % 10 == 0).foreach(group => println(group.sum))

6
задан Community 23 May 2017 в 11:45
поделиться