简体   繁体   中英

Scala equivalent of java.util.Scanner

I am very familiar with using java.util.Scanner with next() , hasNext() , nextInt() , nextLine() , and the like to parse input.

Is there something else I should use in Scala?

This data isn't structured according to a grammar; it's more ad-hoc than that.

For example, lets say I had a inventory. Each line of input starts with the name, then has the quantity of those items, then has the ids for those items

Firetruck 2 A450M A451M
Machine 1 QZLT
Keyboard 0 

I see that Console has methods such as readInt() , but that reads an entire line of input; the equivalent of nextInt() doesn't seem to exist.

java.util.Scanner obviously does the trick. But is there something else I should use (for example, something that returns Scala rather than Java types)?

No there is no equivalent Scala implementation. But I don't see a reason for one as java.util.Scanner would work perfectly fine and all java primitives types would be converted to Scala types implicitly.

So as for "for example, something that returns Scala rather than Java types", Scanner will return scala types when used in scala.

With the input data denoted by spaces and newlines this can be nicely done with map and split on each line from input .

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)

better-files is a Scala library that provides faster, safer and more idiomatic replacement for java.util.Scanner and provides more operations like peeking and scanning.

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

Code sample:

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())
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM