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.