Skip to content

Commit 26d9766

Browse files
anatoliykmetyukjulienrf
authored andcommitted
For-comprehensions article updated with tabs
1 parent 179ad5a commit 26d9766

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

Diff for: _tour/for-comprehensions.md

+61-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Scala offers a lightweight notation for expressing *sequence comprehensions*. Co
1616

1717
Here's an example:
1818

19+
{% tabs for-comprehensions-01 class=tabs-scala-version %}
20+
{% tab 'Scala 2' for=for-comprehensions-01 %}
1921
```scala mdoc
2022
case class User(name: String, age: Int)
2123

@@ -31,23 +33,65 @@ val twentySomethings =
3133

3234
twentySomethings.foreach(println) // prints Travis Dennis
3335
```
36+
{% endtab %}
37+
38+
{% tab 'Scala 3' for=for-comprehensions-01 %}
39+
```scala
40+
case class User(name: String, age: Int)
41+
42+
val userBase = List(
43+
User("Travis", 28),
44+
User("Kelly", 33),
45+
User("Jennifer", 44),
46+
User("Dennis", 23))
47+
48+
val twentySomethings =
49+
for user <- userBase if user.age >=20 && user.age < 30
50+
yield user.name // i.e. add this to a list
51+
52+
twentySomethings.foreach(println) // prints Travis Dennis
53+
```
54+
{% endtab %}
55+
{% endtabs %}
56+
3457

3558
A `for` loop with a `yield` statement returns a result, the container type of which is determined by the first generator. `user <- userBase` is a `List`, and because we said `yield user.name` where `user.name` is a `String`, the overall result is a `List[String]`. And `if user.age >=20 && user.age < 30` is a guard that filters out users who are not in their twenties.
3659

3760
Here is a more complicated example using two generators. It computes all pairs of numbers between `0` and `n-1` whose sum is equal to a given value `v`:
3861

62+
{% tabs for-comprehensions-02 class=tabs-scala-version %}
63+
{% tab 'Scala 2' for=for-comprehensions-02 %}
3964
```scala mdoc
4065
def foo(n: Int, v: Int) =
4166
for (i <- 0 until n;
4267
j <- 0 until n if i + j == v)
4368
yield (i, j)
4469

45-
foo(10, 10) foreach {
70+
foo(10, 10).foreach {
4671
case (i, j) =>
4772
println(s"($i, $j) ") // prints (1, 9) (2, 8) (3, 7) (4, 6) (5, 5) (6, 4) (7, 3) (8, 2) (9, 1)
4873
}
4974

5075
```
76+
77+
{% endtab %}
78+
79+
{% tab 'Scala 3' for=for-comprehensions-02 %}
80+
```scala
81+
def foo(n: Int, v: Int) =
82+
for i <- 0 until n
83+
j <- 0 until n if i + j == v
84+
yield (i, j)
85+
86+
foo(10, 10).foreach {
87+
case (i, j) =>
88+
println(s"($i, $j) ") // prints (1, 9) (2, 8) (3, 7) (4, 6) (5, 5) (6, 4) (7, 3) (8, 2) (9, 1)
89+
}
90+
91+
```
92+
{% endtab %}
93+
{% endtabs %}
94+
5195
Here `n == 10` and `v == 10`. On the first iteration, `i == 0` and `j == 0` so `i + j != v` and therefore nothing is yielded. `j` gets incremented 9 more times before `i` gets incremented to `1`. Without the `if` guard, this would simply print the following:
5296
```scala
5397
(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 0) ...
@@ -57,6 +101,8 @@ Note that comprehensions are not restricted to lists. Every datatype that suppor
57101

58102
You can omit `yield` in a comprehension. In that case, comprehension will return `Unit`. This can be useful in case you need to perform side-effects. Here's a program equivalent to the previous one, but without using `yield`:
59103

104+
{% tabs for-comprehensions-03 class=tabs-scala-version %}
105+
{% tab 'Scala 2' for=for-comprehensions-03 %}
60106
```scala mdoc:nest
61107
def foo(n: Int, v: Int) =
62108
for (i <- 0 until n;
@@ -65,6 +111,20 @@ def foo(n: Int, v: Int) =
65111

66112
foo(10, 10)
67113
```
114+
{% endtab %}
115+
116+
{% tab 'Scala 3' for=for-comprehensions-03 %}
117+
```scala
118+
def foo(n: Int, v: Int) =
119+
for i <- 0 until n
120+
j <- 0 until n if i + j == v
121+
do println(s"($i, $j)")
122+
123+
foo(10, 10)
124+
```
125+
{% endtab %}
126+
{% endtabs %}
127+
68128

69129
## More resources
70130

0 commit comments

Comments
 (0)