0

空白 (改行を含む) で区切られた浮動小数点値を含むテキスト ファイルを処理したいと考えています。任意の大きな入力で作業できるようにしたいのでSource.fromFile(...).mkString、問題外です。次の値が要求されるたびにjava.util.Scannerを呼び出す double のストリームにインスタンスをラップするのは比較的簡単だと思います。このようにして、命令的なアプローチに頼ることなく、ストリームを効率的に減らすことができました。私は次の行で何かを考えています:.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、 に接続hasNext()し、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()
}

これは、 a (Scala だと思います) を実装する Scala の例から改作されていIteratorます。Scala でイテレータを返す方法を参照してください。

于 2013-09-13T00:13:50.747 に答える