2016-04-04 14 views
2

Ben Şimdi v üzerinde f uygulamak ve esaslı bazı sonuçlar seçmek istediğinizScala: Bir koleksiyonu fonksiyonunu uygulamak ve sonuçların bazıları

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

val v = 0 to 10e7.toInt 

v pahalı bir işlevi f ve birçok değerlere sahip olduğunu varsayalım sadece verim bazı durumlarda.

Bu

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

gibi bunu yapabilir Ama bütün v.map(f) ilk hafızada saklanır çünkü bu hiç değil mümkün değil.

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

Ama şimdi söz konusu değildir bazı elementler için iki kez f hesaplamak gerekir:

Öyleyse Diğer seçenek yapmaktır!

Sonuç olarak, tüm sonuçları saklamaksızın filtrelemeyi nasıl gerçekleştirebilirim, ancak yine de sonuçları alırım. mantık (Açıkçası bu işe yaramaz) böyle bir şey gibi görünür:

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

cevap

5

Nasıl iterator hakkında?

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

veya

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

İkisi view herhangi bir ara toplama oluşturmaz. comprehensions için bazı sihirli için görünmüyor arada

, onlar sadece sözdizimsel şeker vardır, bununla kabaca equivalen şeyi yapabilirsiniz:

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) 

Eğer v haritalama gelen iterator olsun istemiyorsanız Tüm koleksiyon, örneklerinizdeki gibi oluşmaya devam eder ve bu nedenle OutOfMemoryError neden olur.

İlgili konular