2014-10-16 54 views
1

我有txt文件,其中包含由“第一:”,“第二:”和“第三:”分隔的3个部分,所有三个将被解析为case class命令。如何迭代需要一些状态的功能,如何解析文件

文件格式:

first: 
blablabla 
blablabla 
blablabla 

second: 
second details blablabla 

third: 
third details blablabla 

的情况下,类命令

case class Command(first: Array[String], 
        second: Array[String], 
        third: Array[String]) 

当我用scalaz流遍历它,我需要实施必要的代码和可变数据处理它在地图上方法。另外,我需要一个状态值,它可以告诉迭代器应该将哪一行放入哪个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 
}) 

我只是想知道我应该如何重构这一个更实用?

提前感谢

+0

我会看看编写一个尾递归函数来构建相应的'ListBuffer'。您可以将'command' case类和'parsingState'作为参数传递给您的尾递归函数。 – 2014-10-16 13:59:47

+0

在这种'map'不是正确的工具的情况下,因为它不能改变流的“形状” - 它只是一个接一个地操作单个元素。你可能想从'io.linesR(...)。split(_。nonEmpty)'开始,或者通过编写单个块的解析器,你可以用'++'顺序编写。 – 2014-10-16 14:00:45

+2

我对斯卡拉斯溪流不熟悉,但你想做的事情看起来像一个折叠非常多。 – rightfold 2014-10-16 18:25:49

回答

-1
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运行此,我编码这个文本框#1内。我鼓励其他人将这些代码封装起来,并将其作为解决方案更好,因为它是不完整的,我现在无法访问Scala编译器。尽管如此,解决方案有一个功能范例。