0

我想处理一个包含由空格分隔的浮点值的文本文件(包括换行符);我希望能够处理任意大的输入,所以这Source.fromFile(...).mkString是毫无疑问的。我认为将实例包装到双打流中应该相对简单,该双打流在每次请求下一个值时都会java.util.Scanner调用。通过这种方式,我可以有效地减少流,而无需采用命令式方法。我正在考虑以下内容:.nextDouble()Scanner

val in = new Scanner(...)
val reducedData = wrapScanner(in).fold(...)

PS不确定“流”是否是正确的术语,但我绝对不是专门指Scala Streams。

PPS 我知道存在,Iterator/Stream.continually但我不知道如何告诉它在哪里停止(以避免NoSuchElementException在文件末尾出现 a)。

4

2 回答 2

0

根据@om-nom-nom 的指导,我提出了以下解决方案:

val in = new java.util.Scanner(...)
val doubles = Iterator
  .continually(if (in.hasNextDouble) Some(in.nextDouble) else None)
  .takeWhile(_ != None)
  .map(_.get)
val sum = doubles.reduce(_ + _)

...但我对摆弄溪流并不是特别高兴;我很乐意接受更清洁的解决方案作为答案。

更新:看起来 Thomas W 找到了一个很好的解决方案;为了完整起见,我将在此处发布:

val in = new Scanner(file)
val it = new Iterator[Double] { def hasNext = in.hasNextDouble; def next = in.nextDouble }
val sum = it.foldLeft(_ + _)
于 2013-09-13T00:13:21.933 回答
0

通常在纯 Java 中,您只需创建一个Iterator包含Scanner, 和 connecthasNext()next()方法到Scanner readDouble().

public class ScanDoubles_Iterator implements Iterator<Double> {
    protected Scanner scanner;
    public boolean hasNext() { return scanner.hasNextDouble(); }
    public Double next() { return scanner.nextDouble(); }
    public void remove() { throw new UnsupportedOperationException(); }
};

让我们复制一些 Scala 示例:

class ScanDoubles_Iterator extends Iterator[Double] {
    val scanner: Scanner = /* init from a constructor */
    def hasNext = scanner.hasNextDouble()
    def next = scanner.nextDouble()
}

这改编自实现 (Scala I假设) 的 Scala 示例Iterator。请参阅如何在 Scala 中返回迭代器?

于 2013-09-13T00:13:50.747 回答