在Scala中表示readline循环的最佳方法?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Scala中表示readline循环的最佳方法?相关的知识,希望对你有一定的参考价值。
来自C / C ++背景,我不太熟悉编程的功能风格,所以我的所有代码都非常必要,因为在大多数情况下我看不到更好的方法。
我只是想知道是否有一种方法可以使这个Scala代码块更“实用”?
var line:String = "";
var lines:String = "";
do {
line = reader.readLine();
lines += line;
} while (line != null)
这个怎么样?
val lines = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString
好吧,在Scala你可以说:
val lines = scala.io.Source.fromFile("file.txt").mkString
但这只是一个库糖。有关其他可能性,请参阅qazxsw poi。您实际要问的是如何将函数范例应用于此问题。这是一个提示:
Read entire file in Scala?
你明白这背后的想法吗?文件中的Source.fromFile("file.txt").getLines().foreach {println}
行执行foreach
函数。顺便说一句,请不要担心,println
返回一个迭代器,而不是整个文件。现在更严重的事情:
getLines()
看到这个想法?拿lines filter {_.startsWith("ab")} map {_.toUpperCase} foreach {println}
(它可以是数组,列表,集合,迭代器,可以过滤的任何东西,其中包含具有lines
方法的项目)和startsWith
仅采用以filter
开头的项目。现在通过应用"ab"
方法获取每个项目和map
。最后toUpperCase
结果项目foreach
它。
最后一个想法:你不仅限于一种类型。例如,假设您有一个包含整数的文件,每行一个。如果你想读取该文件,解析数字并总结它们,只需说:
print
要添加如何使用我投票使用的以前新的lines.map(_.toInt).sum
文件来实现相同的效果,因为它有几个优点:
nio
我发现val path: Path = Paths.get("foo.txt")
val lines = Source.fromInputStream(Files.newInputStream(path)).getLines()
// Now we can iterate the file or do anything we wont, e.g. concatenate
val result = lines.mkString
是一个非常好的方法:它创建一个可重新遍历(如果需要)的序列:
Stream
每个def loadLines(in: java.io.BufferedReader): Stream[String] = {
val line = in.readLine
if (line == null) Stream.Empty
else Stream.cons(line, loadLines(in))
}
元素都有一个值(在这种情况下为Stream
,String
),并调用一个函数(在本例中为line
),它将根据需要懒惰地生成下一个元素。这样可以获得良好的内存使用情况,特别是对于大型数据集 - 在需要之前不会读取行,并且除非某些内容实际上仍然存在,否则不会保留行。然而你也可以回到之前的loadLines(in)
元素并再次向前移动,产生完全相同的结果。
以上是关于在Scala中表示readline循环的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章