Tengo Iterators muy grandes que quiero dividir en pedazos. Tengo un predicado que mira un elemento y devuelve verdadero si es el comienzo de una nueva pieza. Necesito que las piezas sean iteradores, porque incluso las piezas no caben en la memoria. Hay tantas piezas que desconfiaría de una solución recursiva que explote tu pila. La situación es similar a this question, pero necesito Iteradores en lugar de Listas, y los "centinelas" (elementos para los que el predicado es verdadero) ocurren (y deberían incluirse) al comienzo de una pieza. Los iteradores resultantes solo se usarán en orden, aunque algunos no se usarán en absoluto, y solo deberán usar memoria O (1). Me imagino que esto significa que todos deben compartir el mismo iterador subyacente. El rendimiento es importante.Scala: Agrupe un Iterable en un Iterable de Iterables por un predicado
Si tuviera que tomar una puñalada en una firma de función, sería la siguiente:
def groupby[T](iter: Iterator[T])(startsGroup: T => Boolean): Iterator[Iterator[T]] = ...
Me hubiera gustado utilizar takeWhile
, pero pierde el último elemento. Investigué span
, pero amortigua los resultados. Mi mejor idea actual involucra BufferedIterator
, pero tal vez hay una mejor manera.
Usted sabrá que ha hecho bien, porque algo así no se bloquea la 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))
Ver http://stackoverflow.com/questions/5410846/how-do-i-apply-the-pimp-my-library-pattern-to-scala-collections/5411133#5411133 – huynhjl