Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reading 2 files at time (line by line) in scala

Tags:

for-loop

scala

I'm new to scala and I hit this problem:

def main(args: Array[String]){

val source = Source.fromFile(args(0))
val target = Source.fromFile(args(1))

for (lines <- source.getLines ; linet <- target.getLines) { 
  println(lines + " =source| target= " + linet);
}
}

If source and target file contain plain numbers: 1, 2 (one number on each line), the results is:


    1 =source| target= 1 
    1 =source| target= 2

However, I'd expect:


    1 =source| target= 1 
    2 =source| target= 2

Problem: the second file (target) is read correctly (line by line, i.e. 1 and 2), in the first one (source), only the first line (i.e. 1) is read.

Most likely problem lies in for-loop. I though operator ";" behaves like "&&" so one line should be read from both files at time. I tried replaced ";" by "&&" but it didn't work.

any clue will be deeply appreciated! Tomas

like image 621
xhudik Avatar asked Jan 15 '23 19:01

xhudik


1 Answers

You can zip them and iterate through line pairs:

def main(args: Array[String]){

  val source = Source.fromFile(args(0)).getLines
  val target = Source.fromFile(args(1)).getLines

  for ((s,t) <- source.zip(target)) { 
    println(s + " =source| target= " + t);
  }
}

The problem with your approach is that the code written like for(x <- xs, y <- ys) produces cartesian product. In your case it stops to yield items of product as far as first iterator is traversed (bear in mind -- iterators traversable only once).

UPDATE.

Your for loop is analog for this in java/C++/...:

for(int i = 0; i < source.length; i++)
  for(int j = 0; j < target.length; j++) {
    String s = source[i];
    String t = target[j];
    // println ....
  }

(Besides that fact, that above I haven't used iterators)

like image 160
om-nom-nom Avatar answered Jan 17 '23 10:01

om-nom-nom