2013-10-07 103 views
3

我非常熟悉使用java.util.Scannernext(),hasNext(),nextInt(),nextLine()等来解析输入。Scala等效于java.util.Scanner

有什么我应该用在斯卡拉?

该数据不是按照语法来构造的;它比那更特别。

例如,可以说我有一个库存。输入的每一行与所述名称开始,然后具有这些项目的数量,然后对那些项

Firetruck 2 A450M A451M 
Machine 1 QZLT 
Keyboard 0 

我看到Console具有方法如readInt()的ID,但读取输入的一整行;相当于nextInt()似乎并不存在。

java.util.Scanner显然是这样做的。但是有什么我应该使用的(例如,返回Scala而不是Java类型的东西)?

回答

5

不,没有等效的Scala实现。但是我没有看到一个理由,因为java.util.Scanner可以很好地工作,并且所有的java基元类型都会隐式转换为Scala类型。

因此,对于“例如,返回Scala而不是Java类型的东西”,Scanner将在scala中使用时返回scala类型。

+0

“扫描仪将返回Scala中使用时,斯卡拉类型”。哦,当然会。谢谢。 –

1

由空格和换行符表示的输入数据可以在input的每行上使用mapsplit很好地完成。

def input = 
"""Firetruck 2 A450M A451M 
Machine 1 QZLT 
Keyboard 0""" 

case class Item(name: String, quantity: Int, ids: Array[String]) 

scala> input.lines.map(_.split(" ")).map(split => Item(split(0), split(1).toInt, split.takeRight(2))).toList 

res0: List[Item] = List(Item(Firetruck,2,[Ljava.lang.String;@6608842e), Item(Machine,1,[Ljava.lang.String;@391e1c57), Item(Keyboard,0,[Ljava.lang.String;@67d6b10c)) 

scala>res0.foreach(println(_)) 

Item(Firetruck,2,[Ljava.lang.String;@6608842e) 
Item(Machine,1 [Ljava.lang.String;@391e1c57) 
Item(Keyboard,0,[Ljava.lang.String;@67d6b10c) 
+1

s /记录/分隔和s/takeRight/drop –

1

better-files是Scala库,对java.util.Scanner提供更快,更安全,更地道的更换,并提供像窥视和扫描的详细操作。

链接:https://github.com/pathikrit/better-files#scanner

代码示例:

val data = (home/"Desktop"/"stocks.tsv") << s""" 
| id Stock Price Buy 
| --------------------- 
| 1 AAPL 109.16 false 
| 2 GOOGL 566.78 false 
| 3 MSFT 39.10 true 
""".stripMargin 

val scanner: Scanner = data.newScanner.skip(lines = 2) 

assert(scanner.peekLine == Some(" 1 AAPL 109.16 false")) 
assert(scanner.peek == Some("1")) 
assert(scanner.nextInt == Some(1)) 
assert(scanner.peek == Some("AAPL")) 
assert(scanner.nextString() == Some("AAPL")) 
assert(scanner.nextInt() == None) 
assert(scanner.nextDouble() == Some(109.16)) 
assert(scanner.nextBoolean() == Some(false)) 

while(scanner.hasNext) { 
    println(scanner.nextInt(), scanner.next(), scanner.nextDouble(), scanner.nextBoolean()) 
}