2016-04-04 9 views
2

が、私は今、私はvfを適用し、ベースのいくつかの結果を選択したいvスカラ:コレクションに関数を適用し、唯一のいくつかの結果の

def f(x: Int) = { 
    x + 3 
} 

val v = 0 to 10e7.toInt 

に高価な機能f、多くの価値を持っていると仮定し得いくつかの状態で。

私はこの

v.map(f).filter(_ > 10e7 - 5) 

ようにそれを行うことができます。しかし全体v.map(f)は、第1のメモリに保存されますので、それは全く現実的ではないのです。

それでは、他のオプションが行うことです。

for(a <- v if f(a) > 10e7 - 5) yield f(a) 

しかし、今、私は問題外であるいくつかの要素のために二度Fを計算する必要があります!

結果全体を保存せずにフィルタリングを達成するにはどうすれば結果を得ることができますか?論理は次のようになります(明らかにこれは機能しません)。

for(a <- v) { 
    val b = f(a) 
    if(b > 10e7 - 5) yield b 
} 

答えて

5

iteratorはどうですか?

scala> v.iterator.map(f).filter(_ > 10e7 - 5).toVector 
res4: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003) 

またはview

scala> v.view.map(f).filter(_ > 10e7 - 5).toVector 
res5: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003) 

どちらも、任意の中間コレクションを作成しません。ところで

が内包表記のためにいくつかの魔法のために見ていない、彼らは単に構文糖である、あなたはこれで大体equivalenことを行うことができます:あなたはvマッピングからiteratorを得ないだろう場合

scala> (for { 
      a <- v.iterator 
      fa = f(a) 
      if fa > 10e7 - 5 
     } yield fa).toVector 
res9: Vector[Int] = Vector(99999996, 99999997, 99999998, 99999999, 100000000, 100000001, 100000002, 100000003) 

あなたの例のように全体のコレクションが発生して、OutOfMemoryErrorが発生します。

関連する問題