19.3. Przekształcenia pętli i wyrażenia for

Dokładne znaczenie używanych w pętli i wyrażeniu for generatorów i dozorów jest zdefiniowane przez zasady przekształcania pętli i wyrażenia for na wywołania metod map, withFilter, flatMap i foreach. Pętle i wyrażenia for mogą być przekształcone na wyrażenia zawierające wywołania wszystkich lub niektórych ze wspomnianych metod. Ilustrują to poniższe przykłady.

Pętli for niezawierającej słowa kluczowego yield odpowiada wyrażenie zawierające wywołanie metody foreach. Następującej pętli for

scala> for (x <- List(1,2,3)) println(x)
1
2
3

odpowiada wyrażenie

scala> List(1,2,3).foreach{ case x => println(x) }
1
2
3

Wyrażeniu for zawierającemu słowo kluczowe yield odpowiada wyrażenie zawierające wywołanie metody map. Następującemu wyrażeniu for

scala> for (x <- List(1,2,3)) yield x*x
res2: List[Int] = List(1, 4, 9)

odpowiada wyrażenie

scala> List(1,2,3).map{ case x => x*x }
res3: List[Int] = List(1, 4, 9)

Teraz powinno stać się zrozumiałe dlaczego wyrażenia for z poprzedniego punktu zachowywały rodzaj zwracanej kolekcji. Powyższemu wyrażeniu for odpowiada wywołanie metody map na użytej w generatorze kolekcji. Metoda map wywołana na liście zwraca również listę, a wywołana na tablicy zwraca tablicę. Poniższe wyrażenia są również swoimi odpowiednikami i oba zwracają w wyniku tablicę liczb typu Int.

scala> for (x <- Array(1,2,3)) yield x*x
res4: Array[Int] = Array(1, 4, 9)

scala> Array(1,2,3).map{ case x => x*x }
res5: Array[Int] = Array(1, 4, 9)

Wyrażeniu for zawierającemu dwa generatory odpowiada wyrażenie zawierające wywołanie metody flatMap. Następujące dwa wyrażenia są swoimi odpowiednikami.

scala> for (x <- Array(1,2,3); y <- Array(4,5)) yield x*y
res6: Array[Int] = Array(4, 5, 8, 10, 12, 15)

scala> Array(1,2,3).flatMap{ case x => Array(4,5).map{ case y => x*y }}
res7: Array[Int] = Array(4, 5, 8, 10, 12, 15)

Wyrażeniu for zawierającemu generator, po którym występuje dozór, odpowiada wyrażenie zawierające wywołanie metody withFilter. Następujące dwa wyrażenia są swoimi odpowiednikami.

scala> for (x <- Array(1,2,3) if x / 2 != 0) yield x*x
res8: Array[Int] = Array(4, 9)

scala> Array(1,2,3).withFilter(x => x / 2 != 0).map{ case x => x*x }
res9: Array[Int] = Array(4, 9)

Specyfikacja języka Scala opisuje pętlę i wyrażenie for, w tym zasady przekształcania ich na wyrażenia zawierające metody map, withFilter, flatMap i foreach w punkcie 6.19.

Język programowania Scala Wydanie 2. Copyright © Grzegorz Balcerek 2016

Licencja Creative Commons

Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowe.

Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.