Для такого рода проблем я всегда предпочитаю написать собственную хвостовую рекурсивную функцию, работающую o Списки .
import Ordering.Implicits._
def group[A : Ordering](data: List[A], breakPoints: List[A]): List[List[A]] = {
def takeUntil(list: List[A], breakPoint: A): (List[A], List[A]) = {
@annotation.tailrec
def loop(remaining: List[A], acc: List[A]): (List[A], List[A]) =
remaining match {
case x :: xs if (x < breakPoint) =>
loop(remaining = xs, x :: acc)
case _ =>
(acc.reverse, remaining)
}
loop(remaining = list, acc = List.empty)
}
@annotation.tailrec
def loop(remainingElements: List[A], remainingBreakPoints: List[A], acc: List[List[A]]): List[List[A]] =
remainingBreakPoints match {
case breakPoint :: remainingBreakPoints =>
val (group, remaining) = takeUntil(remainingElements, breakPoint)
loop(
remainingElements = remaining,
remainingBreakPoints,
group :: acc
)
case Nil =>
(remainingElements :: acc).reverse
}
loop(
remainingElements = data.sorted,
remainingBreakPoints = breakPoints.sorted,
acc = List.empty
)
}
Вы можете использовать еенапример:
group(data = ('a' to 'z').toList, breakPoints = List('c', 'f', 'j'))
//res: List[List[Char]] = List(
// List('a', 'b'),
// List('c', 'd', 'e'),
// List('f', 'g', 'h', 'i'),
// List('j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
// )
Эта функция всегда генерирует список length = length(breakPoints) + 1
.
Если элементов больше нет, генерируются пустые списки.
(вы можете редактироватькод для ваших конкретных требований)