map- xs.map (x => "x=" + x)
foreach- xs.foreach (x => println ("x=" + x))
yield- for x <- xs yield "x=" + x
do- for x <- xs do println ("x=" + x)
filter- zs.filter (z => z % 3 != 0)
- // shorter: zs.filter(_ % 3 != 0)
- zs.filter (z => z % 3 != 0).
- map (z => "z=" + z)
- for z <- zs
- if z % 3 != 0 yield z
- for z <- zs
- if z % 3 != 0 yield "z=" + z
Multiple iterators
- val xss = List( List(11,21,31), List(), List(41,51) )
- for xs <- xss
- x <- xs
- yield (x, xs.length)
- // res1: List[(Int, Int)] = List((11,3), (21,3), (31,3), (41,2), (51,2))
Cross product of independent iterators
- val xs = List(11,21,31)
- val ys = List("a","b")
- for x <- xs
- y <- ys yield (x, y)
- // res1: List[(Int, String)] = List(
- // (11,a), (11,b),
- // (21,a), (21,b),
- // (31,a), (31,b))
- (for x <- (1 to 7)
- y <- (1 to 9) yield (x, y)
- ).length
- // res1: Int = 63
- val xs = List(11,21,31)
- val ys = List("a","b")
- for x <- xs
- y <- ys yield (x, y)
xs : List[Int]ys : List[String]- x : Int
- y : String
yield provides the type for the result- (x, y) : (Int, String)
- for ... yield (x, y) : List[(Int, String)]
foreach, map, etc. as argumentf do?- def f [X] (xs: List[X]) : List[X] = xs match
- case Nil => Nil
- case y :: ys => f (ys) ::: List (y)
f (Nil)- f (Nil)
- --> Nil
f (3::Nil)- f (3::Nil)
- --> f (Nil) ::: List (3)
- --> Nil ::: List (3)
- --> List (3)
f (2::3::Nil)- f (2::(3::Nil))
- --> f (3::Nil) ::: List (2)
- --> List (3) ::: List (2)
- --> List (3, 2)
f (1::2::3::Nil)- f (1::(2::(3::Nil)))
- --> f (2::(3::Nil)) ::: List (1)
- --> List (3, 2) ::: List (1)
- --> List (3, 2, 1)
f is reverse- def append [X] (xs: List[X], ys: List[X]) : List[X] = xs match
- case Nil => ys
- case z :: zs => z :: append (zs, ys)
- append (1::(2::Nil), 3::Nil)
- --> 1::(append (2::Nil, 3::Nil)) // z = 1, zs = 2::Nil
- --> 1::(2::(append (Nil, 3::Nil))) // z = 2, zs = Nil
- --> 1::(2::(3::Nil)) // z = 2, zs = Nil
1 and 2 created3::Nil is reused (shared)List class has builtin method :::- scala> ((1 to 5).toList) ::: ((10 to 15).toList)
- res1: List[Int] = List(1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15)
Revisit the copy operation
- def copy [X] (xs:List[List[X]]) : List[List[X]] = xs match
- case Nil => Nil
- case y::ys => y :: copy (ys)
- val xss = List(List(11,21,31),List(),List(41,51))
- copy(xss)
- res1: List(List(11,21,31),List(),List(41,51))
Create a copy with a flat structure: replace :: with :::
- def flatten [X] (xs:List[List[X]]) : List[X] = xs match
- case Nil => Nil
- case y::ys => y ::: flatten (ys)
- val xss = List(List(11,21,31),List(),List(41,51))
- flatten(xss)
- res1: List(11,21,31,41,51)
Revisit method map
- def map [X,Y] (xs:List[X], f:X=>List[Y]) : List[List[Y]] = xs match
- case Nil => Nil
- case y::ys => f(y) :: map (ys, f)
- val as = List(3,0,2)
- map (as, (x:Int) => (1 to x).toList)
- res1: List(List(1,2,3), List(), List(1,2))
Create a transformed list with a flat structure: replace :: with :::
- def flatMap [X,Y] (xs:List[X], f:X=>List[Y]) : List[Y] = xs match
- case Nil => Nil
- case y::ys => f(y) ::: flatMap (ys, f)
- val as = List(3,0,2)
- flatMap(as, (x:Int) => (1 to x).toList)
- res1: List(1,2,3,1,2):::Nil
Argument and return types of map and flatMap
map: (List[X],X=>List[Y]) => List[List[Y]]
List[Y]xsflatMap: (List[X],X=>List[Y]) => List[Y]
YList[Y]flatMap- xss.flatMap (x=>x) // same as xss.flatten
- for xs <- xss; x <- xs yield x