Reputation: 5
I am having problems with this function. I need to process more than 1 million records, but this crashes. Looks like just works with thousands of records and throws a StackOverflowError for a larger list. Any suggestions?
def split(list: List[(Pair, Boolean)]): List[List[Pair]] = list match {
case Nil => Nil
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
(head :: l1).map(_._1) :: split(l2)
}
}
Upvotes: 0
Views: 123
Reputation: 688
Your program will throw a StackOverflow exception:
Exception in thread "main" java.lang.StackOverflowError
at scala.collection.immutable.List.map(List.scala:283)
The reason is very simple because your method is not tail-recursive If you annotate it with @tailrec, it won't compile:
@tailrec
def split(list: List[(Pair, Boolean)]): List[List[Pair]] = list match {
case Nil => Nil
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
(head :: l1).map(_._1) :: split(l2)
}
}
The solution is to make your recusion tailrec, or use some kind of loop instead
You could try something like this:
@tailrec
def split(list: List[(Pair, Boolean)], accumulator: List[List[Pair]] = List[List[Pair]]()): List[List[Pair]] = list match {
case Nil => accumulator
case head :: tail => {
val (l1, l2) = tail.span(!_._2)
split(l2, (head :: l1).map(_._1)::accumulator)
}
}
Upvotes: 1