0

I would like to getLine from a Source and convert it to a tuple (Int, Int). I've did it using foreach.

       val values = collection.mutable.ListBuffer[(Int, Int)]()

        Source.fromFile(invitationFile.ref.file).getLines().filter(line => !line.isEmpty).foreach(line => {
          val value = line.split("\\s")

          values += ((value(0).toInt, (value(1).toInt)))
        })

What's the best way to write the same code without use foreach?

3 Answers3

3

Use map, it builds a new list for you:

Source.fromFile(invitationFile.ref.file)
.getLines()
.filter(line => !line.isEmpty)
.map(line => {
  val value = line.split("\\s")
  (value(0).toInt, value(1).toInt)
})
.toList()
Ven
  • 19,015
  • 2
  • 41
  • 61
0

foreach should be a final operation, not a transformation.

In your case, you want to use the function map

val values = Source.fromFile(invitationFile.ref.file).getLines()
  .filter(line => !line.isEmpty)
  .map(line => line.split("\\s"))
  .map(line => (line(0).toInt, line(1).toInt))
puhlen
  • 8,400
  • 1
  • 16
  • 31
0

Using a for comprehension:

val values = for(line <- Source.fromFile(invitationFile.ref.file).getLines(); if !line.isEmpty) {
  val splits = line.split("\\s")
  yield (split(0).toInt, split(1).toInt)
}
David Weiser
  • 5,190
  • 4
  • 28
  • 35
  • when should someone choose a `for` comprehension vs a `map` ? – Tyler Nov 07 '16 at 18:48
  • `for`s are syntactic sugar. See http://stackoverflow.com/questions/1052476/what-is-scalas-yield/1059501#1059501. They'll get compiled into `map` calls (among other calls). I find `for`s easier to read then a bunch of chained `map` calls. – David Weiser Nov 07 '16 at 18:52