我正在使用Scala从2个CSV文件中读取数据,对于第一个文件中的每一行,我想扫描第二个CSV文件中的所有行以进行一些计算。 这是我的代码
object CSVProcess extends App {
val dataMatlab = io.Source.fromFile("./data/data_matlab1.csv")
val matchDataMatlab = io.Source.fromFile("./data/match_data_matlab1.csv")
for ((line, count) <- dataMatlab.getLines.zipWithIndex) {
for ((line1, count1) <- matchDataMatlab.getLines.zipWithIndex) {
println(s"count count1 ${count} ${count1}")
}
}
dataMatlab.close
matchDataMatlab.close
但是,输出不符合我的期望,当第一个CSV文件的第一行扫描第二个CSV文件的所有行时,循环停止。 例如,在CSV 1中,有3行
1,1
2,2
3,3
在CSV 2中,它有3行
1,1,1
2,2,2
3,3,3
但是输出是
count count1 0 0
count count1 0 1
count count1 0 2
输出应为
count count1 0 0
count count1 0 1
count count1 0 2
count count1 1 0
count count1 1 1
count count1 1 2
count count1 2 0
count count1 2 1
count count1 2 2
.
有人可以检测到我的代码问题
答案 0 :(得分:4)
问题是io.Source.fromFiles("path").getLines
给了iterator
,而Iterators
就像 socket缓冲区一样,这意味着一旦您从其中读取数据,没有剩余数据。
official scala documentation解释为
An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator it are next and hasNext. A call to it.next() will return the next element of the iterator and advance the state of the iterator. Calling next again on the same iterator will then yield the element one beyond the one returned previously...
解决方案是将迭代器转换为任何可遍历的对象。在这里,我已将其转换为List以保持持久性。
val dataMatlab = io.Source.fromFile("./data/data_matlab1.csv").getLines().toList
val matchDataMatlab = io.Source.fromFile("./data/match_data_matlab1.csv").getLines().toList
for ((line, count) <- dataMatlab.zipWithIndex) {
for ((line1, count1) <- matchDataMatlab.zipWithIndex) {
println(s"count count1 ${count} ${count1}")
}
}
现在您应该获得预期的输出
我希望说明足够清楚并且有用