Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to represent a readline loop in Scala?

Coming from a C/C++ background, I'm not very familiar with the functional style of programming so all my code tends to be very imperative, as in most cases I just can't see a better way of doing it.

I'm just wondering if there is a way of making this block of Scala code more "functional"?

var line:String = "";
var lines:String = "";

do {
    line = reader.readLine();
    lines += line;
} while (line != null)
like image 426
Kristina Brooks Avatar asked Aug 13 '11 18:08

Kristina Brooks


2 Answers

How about this?

val lines = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString
like image 70
Kipton Barros Avatar answered Sep 19 '22 00:09

Kipton Barros


Well, in Scala you can actually say:

val lines = scala.io.Source.fromFile("file.txt").mkString

But this is just a library sugar. See Read entire file in Scala? for other possiblities. What you are actually asking is how to apply functional paradigm to this problem. Here is a hint:

Source.fromFile("file.txt").getLines().foreach {println}

Do you get the idea behind this? foreach line in the file execute println function. BTW don't worry, getLines() returns an iterator, not the whole file. Now something more serious:

lines filter {_.startsWith("ab")} map {_.toUpperCase} foreach {println}

See the idea? Take lines (it can be an array, list, set, iterator, whatever that can be filtered and which contains an items having startsWith method) and filter taking only the items starting with "ab". Now take every item and map it by applying toUpperCase method. Finally foreach resulting item print it.

The last thought: you are not limited to a single type. For instance say you have a file containing integer number, one per line. If you want to read that file, parse the number and sum them up, simply say:

lines.map(_.toInt).sum
like image 34
Tomasz Nurkiewicz Avatar answered Sep 17 '22 00:09

Tomasz Nurkiewicz