Download presentation
Presentation is loading. Please wait.
Published byShannon Dalton Modified over 8 years ago
1
Sequences and for loops
2
Simple for loops A for loop is used to do something with every element of a sequence scala> for (i <- 2 to 5) println(i + " squared is " + i * i) 2 squared is 4 3 squared is 9 4 squared is 16 5 squared is 25 scala> for (i <- "supercalifragilisticexpealedoceous") print(i + "-") s-u-p-e-r-c-a-l-i-f-r-a-g-i-l-i-s-t-i-c-e-x-p-e-a-l-e-d-o-c-e-o-u-s- scala> var sum = 0; for (i <- 1 to 100) sum = sum + i sum: Int = 5050 So, what is a “sequence”? 2
3
Ranges are sequences scala> 1 to 5 res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5) scala> 1 until 5 res1: scala.collection.immutable.Range = Range(1, 2, 3, 4) scala> Range(1, 5) res2: scala.collection.immutable.Range = Range(1, 2, 3, 4) scala> 1 to 5 by 2 res3: scala.collection.immutable.Range = Range(1, 3, 5) scala> 1 until 5 by 2 res4: scala.collection.immutable.Range = Range(1, 3) scala> Range(1, 5, 2) res5: scala.collection.immutable.Range = Range(1, 3) scala> for (i <- Range(1, 5)) print(i) 1234 3
4
Arrays are sequences scala> Array(2, 3, 5, 7, 11, 13) res0: Array[Int] = Array(2, 3, 5, 7, 11, 13) scala> Array("one", "two", "three") res1: Array[String] = Array(one, two, three) scala> new Array[Int](8) res2: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0) scala> new Array[String](4) res3: Array[String] = Array(null, null, null, null) scala> res3(1) = "one" scala> res3(0) = "zero" scala> res3 res6: Array[String] = Array(zero, one, null, null) 4
5
Vectors are sequences scala> Vector(2, 3, 5, 7, 11, 13) res0: scala.collection.immutable.Vector[Int] = Vector(2, 3, 5, 7, 11, 13) scala> Vector("one", "two", "three") res1: scala.collection.immutable.Vector[String] = Vector(one, two, three) How are Arrays and Vectors different? Arrays are mutable: You can change their contents You saw this on the previous slide Vectors are immutable: You cannot change them How are Arrays and Vectors similar? You can index into them (starting from zero), to find a value scala> res1(0) res12: String = one 5
6
Lists are sequences scala> List(3, 8, 5) res0: List[Int] = List(3, 8, 5) scala> List("hot", "dog") res1: List[String] = List(hot, dog) scala> List(1, 2, 3.75) res2: List[Double] = List(1.0, 2.0, 3.75) scala> List('a', "String", 3, 5.0, true) res3: List[Any] = List(a, String, 3, 5.0, true) scala> for (i <- res3) print(i) aString35.0true 6
7
Strings are (sort of) sequences scala> for (ch <- "abc123") print((ch + 1).toChar) bcd234 scala> "abc123".toCharArray res13: Array[Char] = Array(a, b, c, 1, 2, 3) Strings can be indexed to choose a character scala> var abc123 = "abc123" abc123: String = abc123 scala> abc123(5) res2: Char = 3 Strings are immutable scala> abc123(5) = 'x' :9: error: value update is not a member of String abc123(5) = 'x' But you can create new strings scala> val abc123x = abc123 + 'x' abc123x: String = abc123x 7
8
Immutability and val Variables have values A variable declared with val cannot be assigned a different value This is a property of the variable, not the value But if the value is something that “has contents,” you can change the contents scala> val x = Array(1, 2, 3) x: Array[Int] = Array(1, 2, 3) scala> x(1) = 999 scala> x res1: Array[Int] = Array(1, 999, 3) Immutability is a property of values, not of variables scala> var v = Vector(1, 2, 3) v: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3) scala> v(1) = 999 :9: error: value update is not a member of scala.collection.immutable.Vector[Int] v(1) = 999 ^ 8
9
References 9 val a = 5 5 a val b = ab 5 val x = Array(1, 2, 3) x123 val y = x y x(0) = 9 9
10
for loops with filters So far we’ve only been using the simplest form of a for The first part, variable <- sequence, is a generator For example, n <- 1 to 10 generates the values 1, 2, 3, …, 10 and puts each one in turn into the variable n You can put a filter (a condition) after the generator scala> for (i <- 1 to 8 if i != 5) print(i + " ") 1 2 3 4 6 7 8 You can use more than one condition scala> for (i <- 1 to 24 if 24 % i == 0) print(i + " ") 1 2 3 4 6 8 12 24 It’s more readable (hence, better style) to put the conditions on separate lines scala> for (i <- 1 to 24 | if 24 % i == 0) print(i + " ") 1 2 3 4 6 8 12 24 10
11
for loops with generators You can have more than one generator: scala> for (i <- 1 to 3; j <- 100 to 300 by 50) print((i + j) + " ") 101 151 201 251 301 102 152 202 252 302 103 153 203 253 303 The semicolon is required, even if the generators are on separate lines scala> for (i <- 1 to 3; | j <- 1 to 3) print((i * j) + " ") 1 2 3 2 4 6 3 6 9 You have to start with a generator, but after that you can have generators and filters in any reasonable order 11
12
for loop with variables You can introduce variables scala> for (i <- 1 to 10; j = 3 * i) print(j + " ") 3 6 9 12 15 18 21 24 27 30 Variables introduced in a for loop are automatically val You get a new, “different” val each time through the loop Again, the semicolon is required You have to start with a generator, but after that you can have generators, filters, and new variables in any reasonable order scala> val n = 30 n: Int = 30 scala> for (i <- 1 until n; | sum = i * (i + 1) | if sum == n) { | println(n + " is pronic") | } 30 is pronic 12
13
Sequence comprehensions for ( variable <- sequence ) expression evaluates the expression for each value in the sequence The value of the for expression is just unit—not very useful You use a for loop for what it does (adds up values, prints something, etc.), not for its value for ( variable <- sequence ) yield expression evaluates the expression for each value in the sequence The value of the for-yield expression is a sequence of the values computed by the expression This is a for comprehension or sequence comprehension You use a comprehension for its value Example: scala> for (n <- 1 to 10) yield n * n res6: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) 13
14
Many types of sequences In the previous example, Scala said the type was an IndexedSeq[Int], but printed it as a Vector scala> for (n <- 1 to 10) yield n * n res6: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) Since many operations apply to almost all sequences, you usually don’t have to worry about what kind of sequence you get If you start with a particular kind of sequence, for-yield will (usually) return the same kind of sequence scala> for (n <- Array(1, 3, 5, 7)) yield n * n res11: Array[Int] = Array(1, 9, 25, 49) scala> for (n <- List(1, 3, 5, 7)) yield n * n res12: List[Int] = List(1, 9, 25, 49) scala> for (n <- Range(1, 10, 2)) yield n * n res13: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 9, 25, 49, 81) Notice that this result cannot be expressed as a Range 14
15
Example comprehensions scala> val s = "CIT 591 is my favorite class!" s: String = CIT 591 is my favorite class! scala> for (ch <- s if ch.isLetter) yield ch res14: String = CITismyfavoriteclass scala> val s = "bookkeeper" s: String = bookkeeper scala> for (i <- 0 until s.length – 1 if s(i) == s(i + 1)) yield s(i) res17: scala.collection.immutable.IndexedSeq[Char] = Vector(o, k, e) 15
16
A longer example “rot13” is a simple “secret code,” in which each letter of the alphabet is replaced by one 13 locations away from it scala> def rot13(message: String) = | for (c <- message) yield { | if (c.isLetter) { | val cRotated = (c + 13).toChar | if (cRotated.isLetter) cRotated | else (c - 13).toChar | } | else c | } rot13: (message: String)String scala> rot13("Scala is a great language!") res20: String = Fpnyn vf n terng ynathntr! scala> rot13(rot13("Scala is a great language!")) res21: String = Scala is a great language! 16
17
The End 17 Programmer’s Drinking Song (sung to the tune of “100 Bottles of Beer”) 99 little bugs in the code, 99 bugs in the code, Fix one bug, compile it again, 101 little bugs in the code. 101 little bugs in the code.... (Repeat until BUGS = 0) –Anonymous
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.