progs/lecture2.scala
changeset 320 cdfb2ce30a3d
parent 319 b84ea52bfd8f
child 323 1f8005b4cdf6
equal deleted inserted replaced
319:b84ea52bfd8f 320:cdfb2ce30a3d
   126 
   126 
   127 for (x <- lst) yield x.getOrElse(0)
   127 for (x <- lst) yield x.getOrElse(0)
   128 
   128 
   129 
   129 
   130 // a function that turns strings into numbers (similar to .toInt)
   130 // a function that turns strings into numbers (similar to .toInt)
   131 Integer.parseInt("1234")
   131 Integer.parseInt("12u34")
   132 
   132 
   133 
   133 
   134 def get_me_an_int(s: String) : Option[Int] = 
   134 def get_me_an_int(s: String) : Option[Int] = 
   135  Try(Some(Integer.parseInt(s))).getOrElse(None)
   135  Try(Some(Integer.parseInt(s))).getOrElse(None)
   136 
   136 
   151 List(5,6,7,8,9).indexOf(7)
   151 List(5,6,7,8,9).indexOf(7)
   152 List(5,6,7,8,9).indexOf(10)
   152 List(5,6,7,8,9).indexOf(10)
   153 List(5,6,7,8,9)(-1)
   153 List(5,6,7,8,9)(-1)
   154 
   154 
   155 
   155 
   156 
   156 Try({
       
   157   val x = 3
       
   158   val y = 0
       
   159   Some(x / y)
       
   160 }).getOrElse(None)
   157 
   161 
   158 // Higher-Order Functions
   162 // Higher-Order Functions
   159 //========================
   163 //========================
   160 
   164 
   161 // functions can take functions as arguments
   165 // functions can take functions as arguments
   163 
   167 
   164 def even(x: Int) : Boolean = x % 2 == 0
   168 def even(x: Int) : Boolean = x % 2 == 0
   165 def odd(x: Int) : Boolean = x % 2 == 1
   169 def odd(x: Int) : Boolean = x % 2 == 1
   166 
   170 
   167 val lst = (1 to 10).toList
   171 val lst = (1 to 10).toList
       
   172 lst.reverse.sorted
       
   173 
   168 
   174 
   169 lst.filter(even)
   175 lst.filter(even)
   170 lst.count(even)
   176 lst.count(odd)
   171 lst.find(even)
   177 lst.find(even)
   172 
   178 lst.exists(even)
   173 lst.filter(x => x % 2 == 0)
   179 
       
   180 lst.filter(_ < 4) 
       
   181 lst.filter(x => x % 2 == 1)
   174 lst.filter(_ % 2 == 0)
   182 lst.filter(_ % 2 == 0)
   175 
   183 
   176 lst.sortWith(_ > _)
   184 
       
   185 lst.sortWith((x, y) => x > y)
   177 lst.sortWith(_ < _)
   186 lst.sortWith(_ < _)
   178 
   187 
   179 // but this only works when the arguments are clear, but 
   188 // but this only works when the arguments are clear, but 
   180 // not with multiple occurences
   189 // not with multiple occurences
   181 lst.find(n => odd(n) && n > 2)
   190 lst.find(n => odd(n) && n > 2)
   186 def lex(x: (Int, Int), y: (Int, Int)) : Boolean = 
   195 def lex(x: (Int, Int), y: (Int, Int)) : Boolean = 
   187   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1
   196   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1
   188 
   197 
   189 ps.sortWith(lex)
   198 ps.sortWith(lex)
   190 
   199 
   191 ps.sortBy(_._1)
   200 ps.sortBy(x => x._1)
   192 ps.sortBy(_._2)
   201 ps.sortBy(_._2)
   193 
   202 
   194 ps.maxBy(_._1)
   203 ps.maxBy(_._1)
   195 ps.maxBy(_._2)
   204 ps.maxBy(_._2)
   196 
   205 
   216 
   225 
   217 // this can be iterated
   226 // this can be iterated
   218 
   227 
   219 lst.map(square).filter(_ > 4)
   228 lst.map(square).filter(_ > 4)
   220 
   229 
   221 lst.map(square).filter(_ > 4).map(square)
   230 (lst.map(square)
       
   231    .filter(_ > 4)
       
   232    .map(square))
   222 
   233 
   223 
   234 
   224 // lets define our own higher-order functions
   235 // lets define our own higher-order functions
   225 // type of functions is for example Int => Int
   236 // type of functions is for example Int => Int
       
   237 
       
   238 
       
   239 0 :: List(3,4,5,6)
   226 
   240 
   227 
   241 
   228 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = {
   242 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = {
   229   if (lst == Nil) Nil
   243   if (lst == Nil) Nil
   230   else f(lst.head) :: my_map_int(lst.tail, f)
   244   else f(lst.head) :: my_map_int(lst.tail, f)
   248 // f1: (Int, Int) => Int
   262 // f1: (Int, Int) => Int
   249 // f2: List[String] => Option[Int]
   263 // f2: List[String] => Option[Int]
   250 // ... 
   264 // ... 
   251 val lst = (1 to 10).toList
   265 val lst = (1 to 10).toList
   252 
   266 
   253 def sumOf(f: Int => Int, lst: List[Int]): Int = lst match {
   267 lst.sum
       
   268 
       
   269 val lst = List(1,2,3,4)
       
   270 
       
   271 lst.head
       
   272 lst.tail
       
   273 
       
   274 def sumOf(f: Int => Int, lst: List[Int]): Int = 
       
   275 lst match {
   254   case Nil => 0
   276   case Nil => 0
   255   case x::xs => f(x) + sumOf(f, xs)
   277   case x::foo => f(x) + sumOf(f, foo)
   256 }
   278 }
   257 
   279 
   258 def sum_squares(lst: List[Int]) = sumOf(square, lst)
   280 def sum_squares(lst: List[Int]) = sumOf(square, lst)
   259 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst)
   281 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst)
   260 
   282 
   303 
   325 
   304 lst.flatMap(get_me_an_int).sum
   326 lst.flatMap(get_me_an_int).sum
   305 
   327 
   306 // maps on Options
   328 // maps on Options
   307 
   329 
   308 get_me_an_int("1234").map(even)
   330 get_me_an_int("12345").map(even)
   309 get_me_an_int("12u34").map(even)
   331 get_me_an_int("12u34").map(even)
       
   332 
       
   333 def my_map_option(o: Option[Int], f : Int => Int) : Option[Int] = {
       
   334 o match {
       
   335    case None => None
       
   336    case Some(foo) => Some(f(foo))
       
   337 }}
       
   338 
       
   339 my_map_option(Some(4), square)
       
   340 my_map_option(None, square)
   310 
   341 
   311 
   342 
   312 
   343 
   313 // Map type (upper-case)
   344 // Map type (upper-case)
   314 //=======================
   345 //=======================
   315 
   346 
   316 // Note the difference between map and Map
   347 // Note the difference between map and Map
   317 
   348 
       
   349 val ascii = ('a' to 'z').map(c => (c, c.toInt)).toList
       
   350 
       
   351 val ascii_Map = ascii.toMap
       
   352 
       
   353 
   318 def factors(n: Int) : List[Int] =
   354 def factors(n: Int) : List[Int] =
   319   (2 until n).toList.filter(n % _ == 0)
   355   (2 until n).toList.filter(n % _ == 0)
   320 
   356 
   321 var ls = (1 to 10).toList
   357 var ls = (1 to 10).toList
   322 val facs = ls.map(n => (n, factors(n)))
   358 val facs = ls.map(n => (n, factors(n)))
   325 
   361 
   326 // works for lists of pairs
   362 // works for lists of pairs
   327 facs.toMap
   363 facs.toMap
   328 
   364 
   329 
   365 
   330 facs.toMap.get(4)
   366 facs.toMap.get(40)
   331 facs.toMap.getOrElse(42, Nil)
   367 facs.toMap.getOrElse(42, Nil)
   332 
   368 
   333 val facsMap = facs.toMap
   369 val facsMap = facs.toMap
   334 
   370 
   335 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5))
   371 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5))
   342 // groupBy function on Maps
   378 // groupBy function on Maps
   343 
   379 
   344 val ls = List("one", "two", "three", "four", "five")
   380 val ls = List("one", "two", "three", "four", "five")
   345 ls.groupBy(_.length)
   381 ls.groupBy(_.length)
   346 
   382 
   347 ls.groupBy(_.length).get(3)
   383 ls.groupBy(_.length).get(5)
   348 
   384 
   349 
   385 
   350 
   386 
   351 
   387 
   352 // Pattern Matching
   388 // Pattern Matching
   367 
   403 
   368 
   404 
   369 // recall
   405 // recall
   370 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
   406 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
   371 
   407 
   372 def my_flatten(xs: List[Option[Int]]): List[Int] = xs match {
   408 def my_flatten(xs: List[Option[Int]]): List[Int] = 
       
   409 xs match {
   373   case Nil => Nil 
   410   case Nil => Nil 
   374   case None::rest => my_flatten(rest)
   411   case None::rest => my_flatten(rest)
   375   case Some(v)::rest => v :: my_flatten(rest)
   412   case Some(v)::rest => v :: my_flatten(rest)
   376 }
   413 }
   377 
   414 
   379 
   416 
   380 
   417 
   381 // another example with a default case
   418 // another example with a default case
   382 def get_me_a_string(n: Int): String = n match {
   419 def get_me_a_string(n: Int): String = n match {
   383   case 0 | 1 | 2 => "small"
   420   case 0 | 1 | 2 => "small"
   384   case _ => "big"
   421 }
   385 }
   422 
   386 
   423 get_me_a_string(3)
   387 get_me_a_string(0)
       
   388 
   424 
   389 
   425 
   390 // you can also have cases combined
   426 // you can also have cases combined
   391 def season(month: String) : String = month match {
   427 def season(month: String) : String = month match {
   392   case "March" | "April" | "May" => "It's spring"
   428   case "March" | "April" | "May" => "It's spring"
   444    Combinations of length 3:
   480    Combinations of length 3:
   445    
   481    
   446      aaa, baa, caa, and so on......
   482      aaa, baa, caa, and so on......
   447 */
   483 */
   448 
   484 
       
   485 def combs(cs: List[Char], n: Int) : List[String] = {
       
   486   if (n == 0) List("")
       
   487   else for (c <- cs; s <- combs(cs, n - 1)) yield s"$c$s"
       
   488 }
       
   489 
       
   490 combs(List('a', 'b', 'c'), 3)
       
   491 
       
   492 
       
   493 
   449 def combs(cs: List[Char], l: Int) : List[String] = {
   494 def combs(cs: List[Char], l: Int) : List[String] = {
   450   if (l == 0) List("")
   495   if (l == 0) List("")
   451   else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s"
   496   else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s"
   452 }
   497 }
   453 
   498 
   454 combs("abc".toList, 2)
   499 combs("abc".toList, 2)
   455 
   500 
   456 
       
   457 // another well-known example
       
   458 
       
   459 def move(from: Char, to: Char) =
       
   460   println(s"Move disc from $from to $to!")
       
   461 
       
   462 def hanoi(n: Int, from: Char, via: Char, to: Char) : Unit = {
       
   463   if (n == 0) ()
       
   464   else {
       
   465     hanoi(n - 1, from, to, via)
       
   466     move(from, to)
       
   467     hanoi(n - 1, via, from, to)
       
   468   }
       
   469 } 
       
   470 
       
   471 hanoi(4, 'A', 'B', 'C')
       
   472 
   501 
   473 
   502 
   474 // A Recursive Web Crawler / Email Harvester
   503 // A Recursive Web Crawler / Email Harvester
   475 //===========================================
   504 //===========================================
   476 //
   505 //