2015-11-04 76 views
1

我目前正在開發一個Scala項目。作爲第一次嘗試處理這種困難的項目,我現在非常失落和沮喪。Scala:讀取和過濾行

在這個項目中我應該:

  1. 讀稱爲map.txt一個txt文件,裏面包含了很多的幾個房間 信息
  2. 商店專項線(部分)兩大 陣列的不同元素(房間&動作),它由兩個定義的類組成。

的文件中的行的含義:

  • 在第一行是總數的房間
  • 0在第二行是的所述room_number第一房
  • 哈爾塞爾228是第一個房間的房間
  • 段落是第一個房間的描述
  • 第四行是用戶可以選擇去的不同方向的數量。在這裏是1,因爲用戶在第一個房間只能選擇去往東
  • 在第五行是方向選項,用戶可以選擇去
  • 1除了東是對的room_number選擇去往東的目的地房
  • 然後室1等等等等...

所以在這個的map.txt基本上,我有3個房間:Halsell 228(室1),Halsell第二走廊(房間2),CS辦公室(房間3)

我想我必須利用兩個函數來過濾或取出我想要保存的行的部分。但我真的不知道該怎麼做。這是我想出迄今:

import io.Source 

case class Action(direc: String, dest: Int) 
case class Room(roomNumber: Int, roomName: String, desc: String, array: Array[Action]) 

val source = Source.fromFile("map.txt") 
val lines = source.getLines 

def parseLineR(line: String):Room = { 
    // apparently IDK anything... 
    Room(parts(0).toInt, parts(1),parts(2),parts(3))   
} 

def parseLineD(line: String):Action = { 
    // really don't know 
    Action(parts(0),parts(1).toInt)       
} 

val room =  
val actions = 

source.close 

我要創建兩個數組,這可能看起來像這些:

val rooms = Array(Room(0,"sa","sb",actions),Room(1,"ww","wa",actions),...) 
val actions = Array(Action("east", 0), Action("west", 1),...) 

而且每個數組中的元素的數量應取決於

    在房間
  1. :是總房間數和
  2. 在行動:是的總方向選擇的號碼。
+0

我們無法查看文件時不要求許可。 –

+0

會不會是一個: http://www.cs.trinity.edu/~mlewis/CSCI1320-F12/Code/map.txt – Marco

+0

1.指定的文件格式。你的做法是行不通的,因爲房間信息和方向分佈在多個線路。 2.你最終的數據結構是什麼樣子。你如何檢索房間的方向?或者這些數字是否存在? –

回答

0

您的主要問題是行間存在依賴關係和嚴格的順序。源代碼可能是在這裏使用的錯誤類,因爲它基本上假定你會閱讀幾個相同格式的塊。相反,使用Java Scanner(你可以從Scala的使用沒有問題)。

掃描儀可以讓你得到一件事情的時間,所以你可以做這樣的事情:

case class Action(direc:String, dest:Int) 
case class Room(number:Int, name:String, desc:String, array:Seq[Action]) 

val sc = new java.util.Scanner(new File("map.txt")) 

def readAction() = Action(sc.next(), sc.nextInt()) 

def readRoom() = Room(
    sc.nextInt(), 
    sc.nextLine(), 
    sc.nextLine(), 
    for(i <- 1 to sc.nextInt()) yield readAction() 
) 

val roomCount = sc.nextInt() 
val rooms = for(i <- 1 to roomCount) yield readRoom() 
println(rooms) 
sc.close() 

此打印:

Vector(
    Room(
    0, 
    Halsell 228,  
    You are standing in a room full of computers and comfy chairs with a giant air conditioning unit hanging from the ceiling. While the surroundings are serine enough, you can't help feeling a certain amount of dread. This isn't just a fear that the air conditioning unit is going to fall either. Something in you tells you that this room is regularly used for strange rituals involving torture. You can only wonder what happens here and why there isn't blood all over the place. Your uneasyness makes you want to leave quickly.,Vector(Action(east,1))), Room(1, Halsell 2nd Hallway, This is a long dark hallway with rough carpet and multiple doors leading out. The dispair of lost souls hangs heavily in the air., 
    Vector(
     Action(west,0), 
     Action(east,2) 
    ) 
), 
    Room(
    2, 
    CS Office, 
    You stand in the main office of the Computer Science Department at Trinity University. An overwhelming evil fills the room. It appears to come from one of the many side offices. Looking at the door you see it says 201K. You feel an overwhelming desire to flee this place before work is heaped upon you., 
    Vector(
     Action(west,1) 
    ) 
    ) 
) 

(壓痕礦)

注意您從文件中讀取的順序很重要。如果你說,改變屬性的順序在構造函數,你需要一些中間變量。

+0

請注意,此解決方案,該輸入http://www.cs.trinity.edu/~mlewis/CSCI1320-F12/Code/map.txt –

+0

對不起失敗。使用了錯誤的Scanner構造函數,該構造函數使用參數作爲輸入。通過添加新的'文件( 「的map.txt」)'代替' 「的map.txt」'固定 –

0

下面是使用尾遞歸,圖案MACHING和避免易變性的解決方案:

import io.Source 

case class Action(direc:String, dest:Int) 
object Action { 
    /* Just a helper method, not a big deal */ 
    def apply(line: String): Action = { 
    val columns = line.split(" ") 
    Action(columns(0), columns(1).toInt) 
    } 
} 

case class Room(roomNumber: Int, roomName: String, 
       desc: String, array: List[Action]) 

val source = Source.fromFile("map.txt") 
val lines = source.getLines 

def isNumber(line: String) = line.forall(_.isDigit) 
def isNotNumber(line: String) = ! isNumber(line) 

def parseLines(lines: Seq[String], rs: List[Room]): List[Room] = lines match { 
    case head :: tail if head.forall(_.isSpaceChar) => 
    parseLines(tail, rs) // discard empty lines 
    case head :: tail => 
    val roomLines = head :: tail.takeWhile(isNotNumber) 
    val otherLines = tail.dropWhile(isNotNumber) 
    val newBaseRoom = Room(head.toInt, "", "", List[Action]()) 
    val newRoom = roomLines.foldLeft(newBaseRoom)(parseRoomLine) 
    parseLines(otherLines, rs :+ newRoom) 
    case Nil => rs 
} 

def parseRoomLine(r: Room, iline: String): Room = iline match { 
    case line if line.forall(_.isDigit) => r.copy(roomNumber = line.toInt) 
    case line if line.head.isDigit => 
    r.copy(roomName = line) 
    case text if text.startsWith("east") || text.startsWith("west") => 
    r.copy(array = r.array :+ Action(text)) 
    case text => r.copy(desc = text) 
} 

val rooms = parseLines(lines.toList, List()) 
rooms.foreach(println) 

source.close