Daha sonra map, flatmap vb. İşlevleri uygularken filtre yerine Filtre ile kullanmak her zaman daha performanslı mıdır?
Neden sadece harita, daire haritası ve foreach destekleniyor? (Forall / gibi beklenen işlevler de var)
Daha sonra map, flatmap vb. İşlevleri uygularken filtre yerine Filtre ile kullanmak her zaman daha performanslı mıdır?
Neden sadece harita, daire haritası ve foreach destekleniyor? (Forall / gibi beklenen işlevler de var)
Yanıtlar:
Gönderen Scala docs :
Not: arasındaki fark
c filter pvec withFilter pikincisi sadece müteakip etki alanını kısıtladığı oysa eski yeni koleksiyon oluşturur olmasıdırmap,flatMap,foreach, vewithFilteroperasyonlar.
Böylece filter, orijinal koleksiyonu alacak ve yeni bir koleksiyon üretecek, ancak (filtrelenmiş) koleksiyondan ikinci bir geçişi koruyarak, withFilterfiltrelenmemiş değerleri kesinlikle (yani tembel olarak) daha sonraki map/ flatMap/ withFilterçağrılara geçirecektir. Bu nedenle, bu sonraki yöntem çağrılarına geçerken daha verimli olacaktır.
Aslında, withFilterbu yöntemlerin zincirleriyle çalışmak için özel olarak tasarlanmıştır, bu anlayış için şekeri çözülür. Bunun için başka yöntem ( forall/ gibi exists) gerekmez, bu nedenle FilterMonadicdönüş türüne eklenmemişlerdir withFilter.
viewHaritaların / filtrelerin tembel olmasını istiyorsanız kullanın .
viewve withFilter? Görünüm neden kullanılmıyor for-loops?
Don’t create temporary collectionsbağlantılı bölümde arama yapabilirsiniz .
withFilter, Martin Odersky, bunu şiddetle tavsiye ettiğim Coursera'daki Scala kurslarında açıkça kullanıyor. Bunu yaptığı düşünüldüğünde, diğerlerine de bunu yaparken rahatlık verebilir, ancak aradaki fark tipik olarak sadece 1 karakterdir. Örnek için seq.view filter pvs. seq withFilter p.
Shadowlands'in mükemmel cevabına ek olarak ,filter ve arasındaki farkın sezgisel bir örneğini getirmek istiyorum withFilter.
Aşağıdaki kodu düşünelim
val list = List(1, 2, 3)
var go = true
val result = for(i <- list; if(go)) yield {
go = false
i
}
Çoğu insan resulteşit olmayı bekler List(1). Scala 2.8'den beri durum böyledir, çünkü anlama
val result = list withFilter {
case i => go
} map {
case i => {
go = false
i
}
}
Gördüğünüz gibi çeviri koşulu bir çağrıya dönüştürüyor withFilter. Scala 2.8'den önce, anlama için aşağıdaki gibi bir şeye çevrildi:
val r2 = list filter {
case i => go
} map {
case i => {
go = false
i
}
}
Kullanılması filter, değeri resultoldukça farklı olacaktır: List(1, 2, 3). goBayrak oluşturmamızın falsefiltre üzerinde hiçbir etkisi yoktur, çünkü filtre zaten yapılmıştır. Yine Scala 2.8'de bu sorun kullanılarak çözülmüştür withFilter. Zaman withFilterkullanılır, bu durum bir eleman içinde erişilen her zaman değerlendirilir mapyöntem.
Referans : - s.120, Scala eylemde (Scala 2.10'u kapsar), Manning Yayınları, Milanjan Raychaudhuri - Odersky'nin anlamaya yönelik çeviri hakkındaki düşünceleri
Forall / var olmasının uygulanmamasının ana nedeni , kullanım durumunun şudur:
Forall / var uygulamak için şeyi için tembelliği kaybederek tüm unsurları elde etmemiz gerekir.
Yani mesela:
import scala.collection.AbstractIterator
class RandomIntIterator extends AbstractIterator[Int] {
val rand = new java.util.Random
def next: Int = rand.nextInt()
def hasNext: Boolean = true
}
//rand_integers is an infinite random integers iterator
val rand_integers = new RandomIntIterator
val rand_naturals =
rand_integers.withFilter(_ > 0)
val rand_even_naturals =
rand_naturals.withFilter(_ % 2 == 0)
println(rand_even_naturals.map(identity).take(10).toList)
//calling a second time we get
//another ten-tuple of random even naturals
println(rand_even_naturals.map(identity).take(10).toList)
Ten_rand_even_naturals'ın hala bir yineleyici olduğuna dikkat edin . Sadece dediğimiz zaman ToList rastgele sayılar üretilecek ve zincirde filtrelenecek
Not harita (kimlik) eşdeğerdir map (i => ı) ve orijinal türe withFilter nesne geri dönüştürmek için (örneğin bir koleksiyon, bir dere, bir yineleyici) kullanılır
Verim için kullanmak bir geçici çözüm olabilir, örneğin:
for {
e <- col;
if e isNotEmpty
} yield e.get(0)
Geçici bir çözüm olarak, diğer işlevleri yalnızca mapve ile uygulayabilirsiniz flatMap.
Dahası, bu optimizasyon küçük koleksiyonlarda işe yaramaz ...