mitchus
mitchus

Reputation: 4877

Reading a collection of lists from file in scala

I would like to read a large text file that contains two columns of integers. For each consecutive stretch where the first column is constant, I want to collect the second column as a list. As an example, the following sample

1 2
1 1
1 2
4 3
4 8
1 5
8 2
8 2
8 7

should produce the lists

2,1,2
3,8
5
2,2,7

What is a proper way to achieve this in Scala?

In particular, it would be very nice to have a "lazy" solution, so that I can treat each list without having to first load the entire file into memory.

Upvotes: 1

Views: 1374

Answers (2)

TAKASAKI Hiroaki
TAKASAKI Hiroaki

Reputation: 161

val nums = """(\d+) (\d+)""".r

val tuples = io.Source.fromFile("list.txt").getLines collect {
  case nums(label, num) => (label.toInt -> num.toInt)
}

def toList(tuples: Iterator[(Int, Int)]): Iterator[Seq[Int]] = {
  if(!tuples.hasNext) Iterator.empty
  else {
    val (label, num) = tuples.next
    val (succ, rest) = tuples.span(_._1 == label)
    Iterator(num :: succ.map(_._2).toList) ++ toList(rest)
  }
}

toList(tuples)foreach(println)

Upvotes: 1

drexin
drexin

Reputation: 24423

The simplest way is to use scala.io.Source to read the file line by line. With getLines, you can retrieve an Iterator[String] over which you can map to split the lines and convert them to ints like this:

val intPairs = Source.fromFile("/path/to/file").getLines.map { line =>
  line.split(" ").take(2).map(_.toInt)
}

I leave the grouping of consecutive lines as an exercise for you.

Upvotes: 1

Related Questions