Scala 如果迭代需要某种状态,如何以函数方式解析文件

Scala 如果迭代需要某种状态,如何以函数方式解析文件,scala,functional-programming,Scala,Functional Programming,我有一个txt文件,它包含由“first:”、“second:”和“third:”分隔的3个部分,所有这三个部分都将被解析为case类命令 文件格式: first: blablabla blablabla blablabla second: second details blablabla third: third details blablabla case类命令 case class Command(first: Array[String], se

我有一个txt文件,它包含由“first:”、“second:”和“third:”分隔的3个部分,所有这三个部分都将被解析为case类命令

文件格式:

first:
blablabla
blablabla
blablabla

second:
second details blablabla

third:
third details blablabla
case类命令

case class Command(first: Array[String],
                   second: Array[String],
                   third: Array[String])
当我使用scalaz流对其进行迭代时,我需要实现命令式代码和可变数据,以便在map方法中处理它。另外,我需要一个状态值,它可以告诉迭代器应该将哪一行放入哪个ListBuffer

val firstListBuffer = new ListBuffer[String]
val secondListBuffer = new ListBuffer[String]
val thirdListBuffer = new ListBuffer[String]

var parsingState = ""

io.linesR("testdata/fahrenheit.txt")
    .filter(s => !s.trim.isEmpty)
    .map(t => {
   //if it is first, parsingState = "first"
   //if parsingState = "first", firstListBuffer += t
   //if it is second, parsingState = "second"
   //if parsingState = "second", secondListBuffer += t
   //if it is third, parsingState = "third"
   //if parsingState = "third", thirdListBuffer += t
})
我只是想知道我应该如何重构它,使它更具功能性

非常感谢

abstract class ParsingState
case class First extends ParsingState
case class Second extends ParsingState
case class Third extends ParsingState
case class Command(first:String, second:String, third:String) 

def read(fileName:scala.io.Source):Command = { 
@tailrec
def helper(c:Command) = { 
  val p:ParsingState = //read heading, perform custom logic to assign the correct case class
  val newStrings:String = //read strings after heading, until we hit a new heading, need to return if EOF is hit
  p match { 
    case First => helper(Command(c.first + newStrings,c.second,c.third))
    case Second => helper(Command(c.first,c.second + newStrings, c.third))
    case Third => helper(Command(c.first,c.second,c.third + newStrings))
  } 
}    
helper(Command("","",""))
} 
注:


我没有通过scalac运行这个,我是在Stackoverflow文本框中编写的。我鼓励其他人抄袭这段代码,并将其作为一个更好的解决方案,因为它是不完整的,而且我现在没有访问Scala编译器的权限。不过,这是一个有功能范例的解决方案

我将考虑编写一个尾部递归函数来构建相应的
ListBuffer
。您可以将
命令
case类和
parsingState
作为参数传递给尾部递归函数。在这种情况下,
映射
不是正确的工具,因为它不能更改流的“形状”,它只对单个元素逐个进行操作。您可能希望从类似于
io.linesR(…).split(u.nonEmpty)
的东西开始,或者通过为可以用
++
顺序组合的各个块编写解析器开始。我不熟悉Scalaz流,但您想要做的事情看起来非常像折叠。