Я думаю, что есть много разных способов решить эту проблему.Для меня самым лучшим решением было бы следующее рекурсивное решение:
def filterMessages(l:List[Any]):List[List[Any]] = {
l match {
case "start" :: tail => tail.takeWhile(_ != "end") :: filterMessages(tail.dropWhile(_ != "end"))
case a :: tail => filterMessages(tail)
case Nil => Nil
}
}
Этот подход вернул бы:
scala> val l = "a" :: "b" :: "start" :: 2 :: 1 :: 2:: "crc" :: "end" :: "a" :: "x" :: "start" :: 3 :: 1 :: 2 ::3 :: "crc" :: "end" :: "x" :: Nil
scala> println(filterMessages(l))
res0: List(List(2, 1, 2, crc), List(3, 1, 2, 3, crc))
Если у вас есть «очень длинный» (бесконечный) список, вы должны составитьэтот алгоритм хвостовой рекурсивен.Хвостово-рекурсивное решение выглядело бы так (дает тот же результат, что и выше):
import scala.annotation.tailrec
@tailrec def filterMessages(l:List[Any], result:List[List[Any]]):List[List[Any]] = {
l match {
case "start" :: tail => filterMessages(tail.dropWhile(_ != "end"), tail.takeWhile(_ != "end") :: result)
case a :: tail => filterMessages(tail, result)
case Nil => result
}
}
scala> println(filterMessages(l, Nil))
res0: List(List(2, 1, 2, crc), List(3, 1, 2, 3, crc))
В терминах обработки я бы передал функцию, которая обрабатывает сообщение, а не объединяет каждое сообщение в списке.Это решение будет выглядеть так:
def processMessages(l: List[Any])(process: (List[Any]) => Unit): Unit = {
l match {
case "start" :: tail => process(tail.takeWhile(_ != "end")); processMessages(tail.dropWhile(_ != "end"))(process)
case a :: tail => processMessages(tail)(process)
case Nil => Nil
}
}
Использование:
scala> processMessages(l) { println }