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) |
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)) |
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 // |