3

I want an Enumeratee that groups elements in the Enumerator into groups of up to a max size, where all elements in the group have the same value. So it will scan through the Enumerator and pull values out as long as their value is the same. When it reaches a new value it will roll all the previous results into a list (capping the size). Then it will start a new list with the new value.

So for simplicity, if we had a list like:

[3,3,3,3,3,3,4,4,4,6,6,6,6,6,2,2,2,2,2,2,4,4]

And the max size was 5, then it would partition it like so:

[[3,3,3,3,3],[3],[4,4,4],[6,6,6,6,6],[2,2,2,2,2],[2],[4,4]]

I have been experimenting with various combinations of Enumeratee.grouped, Enumeratee.takeWhile, and Enumeratee.take, but I haven't managed to hit on anything that works yet.

Wade
  • 346
  • 2
  • 12

1 Answers1

1

Your problem can be solved using an Iteratee.fold

val groupingIteratee: Iteratee[Int,List[List[Int]]] = 
  Iteratee.fold(List.empty[List[Int]])(folder(maxElementsInGroup))

where folder is a function defined as (example):

def folder(max: Int) = (list: List[List[Int]], el: Int) => {
          list match {
            case Nil => List(List(el))
            case xs :: rest => {
              xs match {
                case head :: tail if head == el && xs.size < max => (el +: xs) +: rest
                case head :: tail => List(head) +: (xs +: rest)
              }
            }
          }
        }