Skip to content

Commit e3f3041

Browse files
authored
Merge pull request #754 from travissarles/sequence-comp
Rewrote sequence comprehensions section of tour
2 parents 94af7ed + 2c6f8fa commit e3f3041

File tree

2 files changed

+51
-70
lines changed

2 files changed

+51
-70
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
layout: tutorial
3+
title: For Comprehensions
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
categories: tour
9+
num: 17
10+
next-page: generic-classes
11+
previous-page: extractor-objects
12+
---
13+
14+
Scala offers a lightweight notation for expressing *sequence comprehensions*. Comprehensions have the form `for (enumerators) yield e`, where `enumerators` refers to a semicolon-separated list of enumerators. An *enumerator* is either a generator which introduces new variables, or it is a filter. A comprehension evaluates the body `e` for each binding generated by the enumerators and returns a sequence of these values.
15+
16+
Here's an example:
17+
18+
```tut
19+
case class User(val name: String, val age: Int)
20+
21+
val userBase = List(new User("Travis", 28),
22+
new User("Kelly", 33),
23+
new User("Jennifer", 44),
24+
new User("Dennis", 23))
25+
26+
val twentySomethings = for (user <- userBase if (user.age >=20 && user.age < 30))
27+
yield user.name // i.e. add this to a list
28+
29+
twentySomethings.foreach(name => println(name)) // prints Travis Dennis
30+
```
31+
The `for` loop used with a `yield` statement actually creates a `List`. Because we said `yield user.name`, it's a `List[String]`. `user <- userBase` is our iterator and `if (user.age >=20 && user.age < 30)` is a guard that filters out users who are in their 20s.
32+
33+
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`:
34+
35+
```tut
36+
def foo(n: Int, v: Int) =
37+
for (i <- 0 until n;
38+
j <- i until n if i + j == v)
39+
yield (i, j)
40+
41+
foo(10, 10) foreach {
42+
case (i, j) =>
43+
print(s"($i, $j) ") // prints (1, 9) (2, 8) (3, 7) (4, 6) (5, 5)
44+
}
45+
46+
```
47+
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:
48+
```
49+
50+
(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 1) ...
51+
```

tutorials/tour/_posts/2017-02-13-sequence-comprehensions.md

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)