There are two major options to pass a state in functional programming when processing collections (I assume you want to get your result as a variable):
Recursion (classic)
val xs = List("a", "11", "212", "b", "89") @annotation.tailrec def fold(seq: ListBuffer[(String, ListBuffer[String])], xs: Seq[String]): ListBuffer[(String, ListBuffer[String])] = { (seq, xs) match { case (_, Nil) => seq case (_, c :: tail) if toInt(c).isEmpty => fold(seq :+ ((c, ListBuffer[String]())), tail) case (init :+ ((c, seq)), i :: tail) => fold(init :+ ((c, seq :+ i)), tail) } } val result = fold(ListBuffer[(String, ListBuffer[String])](), xs) // Get rid of mutable ListBuffer .toSeq .map { case (c, seq) => (c, seq.toSeq) } //> List((a,List(11, 212)), (b,List(89)))
foldLeft et al.
val xs = List("a", "11", "212", "b", "89") val result = xs.foldLeft( ListBuffer[(String, ListBuffer[String])]() ) { case (seq, c) if toInt(c).isEmpty => seq :+ ((c, ListBuffer[String]())) case (init :+ ((c, seq)), i) => init :+ ((c, seq :+ i)) } // Get rid of mutable ListBuffer .toSeq .map { case (c, seq) => (c, seq.toSeq) } //> List((a,List(11, 212)), (b,List(89)))
Which one is better? Unless you want to abort your processing in the middle of your collection (like e.g. in find) foldLeft is considered a better way and it has slightly less boilerplate, but otherwise they are very similar.
I'm using ListBuffer here to avoid reversing lists.
foldLeftis what is used in FP to keep state