28

すべての値を評価せずに、yieldをイテレータとして使用することは可能ですか?

Iterator複雑なリスト生成を実装するのが簡単で、結果を必要としないため、それをに変換する必要がある場合、これは一般的なタスクです...

4

3 に答える 3

51

もちろん。実際、非厳密性には3つのオプションがあり、以下にリストします。例として、次のことを想定します。

val list = List.range(1, 10)
def compute(n: Int) = {
    println("Computing "+n)
    n * 2
}
  1. Stream。AStreamは遅延評価されたリストです。オンデマンドで値を計算しますが、一度計算されると値を再計算しません。ストリームの一部を何度も再利用する場合に最も役立ちます。たとえば、以下のコードを実行すると、「Computing 1」、「Computing 2」、「Computing3」がそれぞれ1回ずつ出力されます。

    val stream = for (n <- list.toStream) yield compute(n)
    val third = stream(2)
    println("%d %d" format (third, stream(2)))
    
  2. ビュー。_ ビューは、基本コレクションに対する操作の組み合わせです。ビューを調べるとき、調べられる各要素はオンデマンドで計算されます。ビューにランダムにアクセスする場合に最も役立ちますが、ビューのごく一部を見るだけです。たとえば、以下のコードを実行すると、「Computing 3」が2回出力され、それ以外は何も出力されません(結果以外は)。

    val view = for (n <- list.view) yield compute(n)
    val third = view(2)
    println("%d %d" format (third, view(2)))
    
  3. Iterator。AnIteratorは、コレクションをゆっくりと歩くために使用されるものです。いわば「ワンショット」コレクションと考えることができます。要素を再計算したり保存したりすることはありません。要素が「計算」されると、再度使用することはできません。そのため、使用するのは少し難しいですが、これらの制約を考慮すると、最も効率的な方法です。たとえば、次の例は、Iteratorインデックス付きアクセスをサポートしていないため(このように記述した場合、ビューのパフォーマンスが低下するため)、異なる必要があります。以下のコードは、「Computing 1」、「Computing 2」、「Computing 3」、「コンピューティング4」、「コンピューティング5」、「コンピューティング6」。また、最後に2つの異なる数値を出力します。

    val iterator = for (n <- list.iterator) yield compute(n)
    val third = iterator.drop(2).next
    println("%d %d" format (third, iterator.drop(2).next))
    
于 2010-12-24T12:21:03.530 に答える
3

遅延評価が必要な場合は、ビューを使用してください。ビューを参照してください。

Scalaコレクションを頻繁に使用する場合、 Scala2.8コレクションAPIは素晴らしい読み物です。

于 2010-12-24T09:46:17.357 に答える
2

私はList...

scala>  List(1, 2, 3)
res0: List[Int] = List(1, 2, 3)

そして関数..。

scala> def foo(i : Int) : String = { println("Eval: " + i); i.toString + "Foo" }
foo: (i: Int)String

そして今、私は理解のためIterator...

scala> for { i <- res0.iterator } yield foo(i)
res2: Iterator[java.lang.String] = non-empty iterator

flatMapmapおよびfilterメソッドを使用すると、任意のタイプの理解にforを使用できます。ビューを使用することもできます:

scala> for { i <- res0.view } yield foo(i)
res3: scala.collection.SeqView[String,Seq[_]] = SeqViewM(...)

どちらの場合も評価は厳密ではありません...

scala> res3.head
Eval: 1
res4: String = 1Foo
于 2010-12-24T12:05:59.850 に答える