Czy zawsze bardziej wydajne jest użycie withFilter zamiast filtra, gdy później stosuje się funkcje takie jak mapa, mapa płaska itp.?
Dlaczego obsługiwane są tylko mapy, mapy płaskie i wszystkie? (Oczekiwane funkcje, takie jak forall / również istnieją)
Odpowiedzi:
Z dokumentów Scala :
Więc
filter
weźmie oryginalną kolekcję i utworzy nową kolekcję, alewithFilter
nieściśle (tj. Leniwie) przekaże niefiltrowane wartości do późniejszych wywołańmap
/flatMap
/withFilter
, oszczędzając drugie przejście przez (filtrowaną) kolekcję. W związku z tym będzie bardziej wydajne podczas przechodzenia do tych kolejnych wywołań metod.W rzeczywistości
withFilter
jest specjalnie zaprojektowany do pracy z łańcuchami tych metod, co jest tym, do czego służy zrozumienie. Żadne inne metody (takie jakforall
/exists
) nie są do tego wymagane, więc nie zostały dodane doFilterMonadic
zwracanego typuwithFilter
.źródło
view
jeśli chcesz, aby mapy / filtry były leniwe.view
iwithFilter
? Dlaczego widok nie jest używany dofor-loops
?Don’t create temporary collections
w połączonej sekcji.withFilter
, sam Martin Odersky używa go wyraźnie w swoich kursach Scala na Coursera, które bardzo polecam. Biorąc pod uwagę, że to robi, może to również dać innym pocieszenie, chociaż różnica jest zwykle tylko 1 znakiem. Na przykładseq.view filter p
vs.seq withFilter p
.Oprócz doskonałej odpowiedzi Shadowlands , chciałbym przedstawić intuicyjny przykład różnicy między
filter
iwithFilter
.Rozważmy następujący kod
val list = List(1, 2, 3) var go = true val result = for(i <- list; if(go)) yield { go = false i }
Większość ludzi oczekuje,
result
że będzie im równaList(1)
. Dzieje się tak od wersji Scala 2.8, ponieważ rozumienie tekstu jest tłumaczone naval result = list withFilter { case i => go } map { case i => { go = false i } }
Jak widać, tłumaczenie konwertuje warunek na wywołanie
withFilter
. Wcześniej Scala 2.8, rozumienie zostało przetłumaczone na coś takiego:val r2 = list filter { case i => go } map { case i => { go = false i } }
Korzystanie
filter
wartośćresult
byłaby całkiem inna:List(1, 2, 3)
. Fakt, że tworzymygo
flagę,false
nie ma wpływu na filtr, ponieważ filtr jest już gotowy. Ponownie, w Scali 2.8 ten problem został rozwiązany za pomocąwithFilter
. GdywithFilter
jest używany, warunek jest oceniany za każdym razem, gdy uzyskuje się dostęp do elementu wewnątrzmap
metody.Referencyjne : - str.120, Scala w działaniu (pokrowce Scala 2.10), Manning Publications, Milanjan Raychaudhuri - myśli Odersky chodzi o do-zrozumienia tłumaczenia
źródło
Głównym powodem, dla którego nie zaimplementowano forall / existie, jest taki przypadek użycia:
Aby zaimplementować wszystko / istnieje , musimy uzyskać wszystkie elementy, tracąc lenistwo.
Na przykład:
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)
Zauważ, że ten_rand_even_naturals nadal jest iteratorem. Dopiero gdy wywołasz toList, losowe liczby zostaną wygenerowane i odfiltrowane w łańcuchu
Zauważ, że map (identity) jest równoważne map (i => i) i jest używane tutaj w celu konwersji obiektu withFilter z powrotem do typu oryginalnego (np. Kolekcja, strumień, iterator)
źródło
Dla części dla wszystkich / istniejących:
byłoby takie samo jak (choć trochę nieintuicyjne)
Podobnie, .filter (). Exist () może zostać połączone w jeden exist () check?
źródło
Używanie do uzyskiwania plonów może być obejściem, na przykład:
for { e <- col; if e isNotEmpty } yield e.get(0)
źródło
Aby obejść ten problem, możesz zaimplementować inne funkcje tylko z
map
iflatMap
.Ponadto ta optymalizacja jest bezużyteczna w przypadku małych kolekcji…
źródło